Rewrite of the installation script and accompanying documentation. (#15)
Rewrite of the installation script and accompanying documentation.
This commit is contained in:
parent
0d69f4f49b
commit
760b8d95fb
|
@ -6,3 +6,4 @@ node_modules
|
|||
prep.config
|
||||
target
|
||||
ui-dist
|
||||
yarn-error.log
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
# Installing Moonfire NVR using provided scripts
|
||||
|
||||
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.
|
||||
You'll start by downloading moonfire if you have not already done so.
|
||||
|
||||
## 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 command line via git:
|
||||
|
||||
$ git clone https://github.com/scottlamb/moonfire-nvr.git
|
||||
|
||||
## Preparation steps for easy install
|
||||
|
||||
There are a few things to prepare if you want a truly turnkey install, but
|
||||
they are both optional.
|
||||
|
||||
### Dedicated media directory
|
||||
|
||||
An optional, but strongly suggested, step is to setup a dedicated hard disk
|
||||
for recording video.
|
||||
Moonfire works best if the video samples are collected on a hard drive of
|
||||
sufficient capacity and separate from the root and main file systems. This
|
||||
is particularly important on Raspberry Pi based systems as the flash based
|
||||
main file systems have a limited lifetime and are way too small to hold
|
||||
any significant amount of video.
|
||||
If a dedicated hard drive is available, set up the mount point (in this
|
||||
example we'll use /media/nvr/samples):
|
||||
|
||||
$ sudo vim /etc/fstab
|
||||
$ sudo mount /mount/media/samples
|
||||
|
||||
In the fstab you would add a line similar to this:
|
||||
|
||||
/dev/disk/by-uuid/23d550bc-0e38-4825-acac-1cac8a7e091f /media/nvr ext4 defaults,noatime 0 1
|
||||
|
||||
You'll have to lookup the correct uuid for your disk. One way to do that is
|
||||
to issue the following commands:
|
||||
|
||||
$ ls -l /dev/disk/by-uuid
|
||||
|
||||
Locate the device where your disk will be mounted (or is mounted), for example
|
||||
`/dev/sda1`. Now lookup the filename linked to that from the output of the
|
||||
`ls` command. This is the uuid you need.
|
||||
|
||||
The setup script (see below) will create the necessary sample file dir on the mounted
|
||||
hard disk.
|
||||
|
||||
|
||||
## Setting everything up
|
||||
|
||||
Start by executing the setup script:
|
||||
|
||||
$ cd moonfire-nr
|
||||
$ 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.
|
||||
|
||||
*WARNING* 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. In the most frequent
|
||||
scenarios you will probably only change SAMPLE_MEDIA_DIR to point
|
||||
to your mounted external disk (/media/nvr in the example above).
|
||||
|
||||
NVR_USER=moonfire-nvr
|
||||
NVR_GROUP=$NVR_USER
|
||||
NVR_PORT=8080
|
||||
NVR_HOME_BASE=/var/lib
|
||||
DB_NAME=db
|
||||
DB_DIR=$NVR_HOME/$DB_NAME
|
||||
SAMPLE_FILE_DIR=sample
|
||||
SAMPLE_MEDIA_DIR=$NVR_HOME
|
||||
SERVICE_NAME=moonfire-nvr
|
||||
SERVICE_DESC="Moonfire NVR"
|
||||
SERVICE_BIN=/usr/local/bin/$SERVICE_NAME
|
|
@ -0,0 +1,202 @@
|
|||
# Installing Moonfire NVR
|
||||
|
||||
This document describes how to install Moonfire NVR on a Linux system.
|
||||
|
||||
## 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 command line via git:
|
||||
|
||||
$ git clone https://github.com/scottlamb/moonfire-nvr.git
|
||||
|
||||
## 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 \
|
||||
libssl-dev \
|
||||
pkgconf
|
||||
|
||||
Next, you need Rust 1.17+ 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/).
|
||||
|
||||
You can continue to follow the build/install instructions below for a manual
|
||||
build and install, or alternatively you can run the prep script called `prep.sh`.
|
||||
|
||||
$ cd moonfire-nvr
|
||||
$ ./prep.sh
|
||||
|
||||
The script will take the following command line options, should you need them:
|
||||
|
||||
* `-S`: Skip updating and installing dependencies through apt-get. This too can be
|
||||
useful on repeated builds.
|
||||
|
||||
You can edit variables at the start of the script to influence names and
|
||||
directories, but defaults should suffice in most cases. For details refer to
|
||||
the script itself. We will mention just one option, needed when you follow the
|
||||
suggestion to separate database and samples between flash storage and a hard disk.
|
||||
If you have the hard disk mounted on, lets say `/media/nvr`, and you want to
|
||||
store the video samples inside a directory named `samples` there, you would set:
|
||||
|
||||
SAMPLE_FILE_DIR=/media/nvr/samples
|
||||
|
||||
The script will perform all necessary steps to leave you with a fully built,
|
||||
installed moonfire-nvr binary. The only thing
|
||||
you'll have to do manually is add your camera configuration(s) to the database.
|
||||
Alternatively, before running the script, you can create a file named `cameras.sql`
|
||||
in the same directory as the `prep.sh` script and it will be automatically
|
||||
included for you.
|
||||
For instructions, you can skip to "[Camera configuration and hard disk mounting](#camera)".
|
||||
|
||||
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
|
||||
|
||||
## Further configuration
|
||||
|
||||
Moonfire NVR should be run under a dedicated user. It keeps two kinds of
|
||||
state:
|
||||
|
||||
* a SQLite database, typically <1 GiB. It should be stored on flash if
|
||||
available.
|
||||
* the "sample file directory", which holds the actual samples/frames of
|
||||
H.264 video. This should be quite large and typically is stored on a hard
|
||||
drive.
|
||||
|
||||
(See [schema.md](schema.md) for more information.)
|
||||
|
||||
Both kinds of state are intended to be accessed only by Moonfire NVR itself.
|
||||
However, the interface for adding new cameras is not yet written, so you will
|
||||
have to manually insert cameras with the `sqlite3` command line tool prior to
|
||||
starting Moonfire NVR.
|
||||
|
||||
Manual commands would look something like this:
|
||||
|
||||
$ sudo addgroup --system moonfire-nvr
|
||||
$ sudo adduser --system moonfire-nvr --home /var/lib/moonfire-nvr
|
||||
$ sudo mkdir /var/lib/moonfire-nvr
|
||||
$ sudo -u moonfire-nvr -H mkdir db sample
|
||||
$ sudo -u moonfire-nvr moonfire-nvr init
|
||||
|
||||
### <a name="cameras"></a>Camera configuration and hard drive mounting
|
||||
|
||||
If a dedicated hard drive is available, set up the mount point:
|
||||
|
||||
$ sudo vim /etc/fstab
|
||||
$ sudo mount /var/lib/moonfire-nvr/sample
|
||||
|
||||
Once setup is complete, it is time to add camera configurations to the
|
||||
database. If the daemon is running, you will need to stop it temporarily:
|
||||
|
||||
$ sudo systemctl stop moonfire-nvr
|
||||
|
||||
You can configure the system through a text-based user interface:
|
||||
|
||||
$ sudo -u moonfire-nvr moonfire-nvr config 2>debug-log
|
||||
|
||||
In the user interface, add your cameras under the "Edit cameras" dialog.
|
||||
There's a "Test" button to verify your settings directly from the dialog.
|
||||
|
||||
After the cameras look correct, go to "Edit retention" to assign disk space to
|
||||
each camera. Leave a little slack (at least 100 MB per camera) between the total
|
||||
limit and the filesystem capacity, even if you store nothing else on the disk.
|
||||
There are several reasons this is needed:
|
||||
|
||||
* The limit currently controls fully-written files only. There will be up
|
||||
to two minutes of video per camera of additional video.
|
||||
* The rotation happens after the limit is exceeded, not proactively.
|
||||
* Moonfire NVR currently doesn't account for the unused space in the final
|
||||
filesystem block at the end of each file.
|
||||
* Moonfire NVR doesn't account for the space used for directory listings.
|
||||
* If a file is open when it is deleted (such as if a HTTP client is
|
||||
downloading it), it stays around until the file is closed. Moonfire NVR
|
||||
currently doesn't account for this.
|
||||
|
||||
When finished, start the daemon:
|
||||
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
|
||||
### System Service
|
||||
|
||||
Moonfire NVR can be run as a systemd service. If you used `prep.sh` this has
|
||||
been done for you. If not, Create
|
||||
`/etc/systemd/system/moonfire-nvr.service`:
|
||||
|
||||
[Unit]
|
||||
Description=Moonfire NVR
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/local/bin/moonfire-nvr run \
|
||||
--sample-file-dir=/var/lib/moonfire-nvr/samples \
|
||||
--db-dir=/var/lib/moonfire-nvr/db \
|
||||
--http-addr=0.0.0.0:8080
|
||||
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-abnormal
|
||||
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.
|
||||
|
||||
Complete the installation through `systemctl` commands:
|
||||
|
||||
$ sudo systemctl daemon-reload
|
||||
$ sudo systemctl start moonfire-nvr
|
||||
$ sudo systemctl status moonfire-nvr
|
||||
$ sudo systemctl enable moonfire-nvr
|
||||
|
||||
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.
|
106
guide/install.md
106
guide/install.md
|
@ -13,84 +13,17 @@ edge version from the command line via git:
|
|||
## Building from source
|
||||
|
||||
There are no binary packages of Moonfire NVR available yet, so it must be built
|
||||
from source.
|
||||
from source. To do so, you can follow two paths:
|
||||
|
||||
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.
|
||||
* Scripted install: 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. This process is fully
|
||||
described. Read more in [Easy Installation](easy-install.md)
|
||||
* Manual build and install. This is explained in detail in these
|
||||
[instructions](install-manual.md)
|
||||
|
||||
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 not 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 \
|
||||
libssl-dev \
|
||||
pkgconf
|
||||
|
||||
Next, you need Rust 1.17+ 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/).
|
||||
|
||||
You can continue to follow the build/install instructions below for a manual
|
||||
build and install, or alternatively you can run the prep script called `prep.sh`.
|
||||
|
||||
$ cd moonfire-nvr
|
||||
$ ./prep.sh
|
||||
|
||||
The script will take the following command line options, should you need them:
|
||||
|
||||
* `-S`: Skip updating and installing dependencies through apt-get. This too can be
|
||||
useful on repeated builds.
|
||||
|
||||
You can edit variables at the start of the script to influence names and
|
||||
directories, but defaults should suffice in most cases. For details refer to
|
||||
the script itself. We will mention just one option, needed when you follow the
|
||||
suggestion to separate database and samples between flash storage and a hard disk.
|
||||
If you have the hard disk mounted on, lets say `/media/nvr`, and you want to
|
||||
store the video samples inside a directory named `samples` there, you would set:
|
||||
|
||||
SAMPLES_DIR=/media/nvr/samples
|
||||
|
||||
The script will perform all necessary steps to leave you with a fully built,
|
||||
installed moonfire-nvr binary. The only thing
|
||||
you'll have to do manually is add your camera configuration(s) to the database.
|
||||
Alternatively, before running the script, you can create a file named `cameras.sql`
|
||||
in the same directory as the `prep.sh` script and it will be automatically
|
||||
included for you.
|
||||
For instructions, you can skip to "[Camera configuration and hard disk mounting](#camera)".
|
||||
|
||||
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
|
||||
Regardless of the approach for setup and installation above that you choose,
|
||||
please read the further configuration instructions below.
|
||||
|
||||
## Further configuration
|
||||
|
||||
|
@ -103,13 +36,13 @@ state:
|
|||
H.264 video. This should be quite large and typically is stored on a hard
|
||||
drive.
|
||||
|
||||
Both states are intended to be accessed by moonfire-nvr only, but can be
|
||||
changed after building. See below.
|
||||
(See [schema.md](schema.md) for more information.)
|
||||
|
||||
Both kinds of state are intended to be accessed only by Moonfire NVR itself.
|
||||
However, the interface for adding new cameras is not yet written, so you will
|
||||
have to manually insert cameras with the `sqlite3` command line tool prior to
|
||||
starting Moonfire NVR.
|
||||
|
||||
The database changes and sample file directory changes require the moonfire-nvr
|
||||
binary to be built, so can only be done after completing the build. The other
|
||||
settings and preparations should be done before building.
|
||||
Manual commands would look something like this:
|
||||
|
||||
$ sudo addgroup --system moonfire-nvr
|
||||
|
@ -118,7 +51,7 @@ Manual commands would look something like this:
|
|||
$ sudo -u moonfire-nvr -H mkdir db sample
|
||||
$ sudo -u moonfire-nvr moonfire-nvr init
|
||||
|
||||
### <a name="cameras"></a>Camera configuration and hard drive mounting
|
||||
### <a name="drive mounting"></a>Camera configuration and hard drive mounting
|
||||
|
||||
If a dedicated hard drive is available, set up the mount point:
|
||||
|
||||
|
@ -130,10 +63,17 @@ database. If the daemon is running, you will need to stop it temporarily:
|
|||
|
||||
$ sudo systemctl stop moonfire-nvr
|
||||
|
||||
You can configure the system through a text-based user interface:
|
||||
You can configure the system's database through a text-based user interface:
|
||||
|
||||
$ sudo -u moonfire-nvr moonfire-nvr config 2>debug-log
|
||||
|
||||
If you have used a non-default path for your samples directory, as you most
|
||||
likely have, you must also supply that location, or the command will fail
|
||||
with an error message about not being able to open the default location for
|
||||
that directory:
|
||||
|
||||
$ sudo -u moonfire-nvr moonfire-nvr config --sample-files-dir=/path/to/my/media/samples 2>debug-log
|
||||
|
||||
In the user interface, add your cameras under the "Edit cameras" dialog.
|
||||
There's a "Test" button to verify your settings directly from the dialog.
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
"url": "https://github.com/scottlamb/moonfire-nvr/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack && ln ui-src/index.html ui-dist/"
|
||||
"clean": "scripts/clean.sh",
|
||||
"build": "webpack && ln -f ui-src/index.html ui-dist/"
|
||||
},
|
||||
"dependencies": {
|
||||
"jquery": "^3.2.1",
|
||||
|
@ -24,6 +25,6 @@
|
|||
"css-loader": "^0.28.7",
|
||||
"file-loader": "^1.1.5",
|
||||
"style-loader": "^0.19.0",
|
||||
"webpack": "^3.8.1"
|
||||
"webpack": "3.8.1"
|
||||
}
|
||||
}
|
||||
|
|
278
prep.sh
278
prep.sh
|
@ -1,278 +0,0 @@
|
|||
#!/bin/bash -x
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016 Scott Lamb <slamb@slamb.org>
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
#
|
||||
# Script to prepare for moonfire-nvr operations
|
||||
#
|
||||
# Command line options:
|
||||
# -S: Skip apt-get update and install
|
||||
#
|
||||
|
||||
# Configuration variables. Should only need minimal, or zero, changes.
|
||||
# Empty values will use defaults. For convenience, we attempt to read
|
||||
# customizations from prep.config first
|
||||
#
|
||||
if [ -r prep.config ]; then
|
||||
. prep.config
|
||||
fi
|
||||
|
||||
# User and group
|
||||
# Default: or whatever is in $NVR_USER (default "moonfire-nvr")
|
||||
#
|
||||
#NVR_USER=
|
||||
#NVR_GROUP=
|
||||
|
||||
# Port for web server
|
||||
# Default: 8080
|
||||
#
|
||||
#NVR_PORT=
|
||||
|
||||
# This should, ideally, be a location on flash storage under which the
|
||||
# moonfire user's home directory will be created.
|
||||
# Default: "/var/lib"
|
||||
#
|
||||
#NVR_HOME_BASE=
|
||||
|
||||
# Set to mountpoint of media directory, empty to stay in home directory
|
||||
# Default: empty
|
||||
#SAMPLES_DIR=/media/nvr/samples
|
||||
|
||||
# Set to path for media directory relative to mountpoint
|
||||
# Default: "samples"
|
||||
#
|
||||
#SAMPLES_DIR_NAME=
|
||||
|
||||
# Binary location
|
||||
# Default: "/usr/local/bin/moonfire-nvr"
|
||||
#
|
||||
#SERVICE_BIN=
|
||||
|
||||
# Resource files location
|
||||
# Default: "/usr/local/lib/moonfire-nvr"
|
||||
#LIB_DIR=/usr/local/lib/moonfire-nvr
|
||||
|
||||
# Service name
|
||||
# Default: "moonfire-nvr"
|
||||
#
|
||||
#SERVICE_NAME=
|
||||
|
||||
# Service Description
|
||||
# Default: "Moonfire NVR"
|
||||
#
|
||||
#SERVICE_DESC=
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Derived variables: Do not modify!
|
||||
#
|
||||
# Determine directory path of this script
|
||||
#
|
||||
SOURCE="${BASH_SOURCE[0]}"
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until file no longer a symlink
|
||||
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
||||
SOURCE="$(readlink "$SOURCE")"
|
||||
# if $SOURCE was relative symlink, resolve relative to path of symlink
|
||||
[[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE"
|
||||
done
|
||||
|
||||
SRC_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"/src
|
||||
NVR_USER="${NVR_USER:-moonfire-nvr}"
|
||||
NVR_GROUP="${NVR_GROUP:-$NVR_USER}"
|
||||
NVR_PORT="${NVR_PORT:-8080}"
|
||||
NVR_HOME_BASE="${NVR_HOME_BASE:-/var/lib}"
|
||||
NVR_HOME="${NVR_HOME_BASE}/${NVR_USER}"
|
||||
DB_DIR="${DB_DIR:-$NVR_HOME/db}"
|
||||
SAMPLES_DIR_NAME="${SAMPLES_DIR_NAME:-samples}"
|
||||
SAMPLES_DIR="${SAMPLES_DIR:-$NVR_HOME/$SAMPLES_DIR_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}"
|
||||
|
||||
# Process command line options
|
||||
#
|
||||
while getopts ":DS" opt; do
|
||||
case $opt in
|
||||
S) SKIP_APT=1
|
||||
;;
|
||||
:)
|
||||
echo "Option -$OPTARG requires an argument." >&2
|
||||
exit 1
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Setup all apt packages we need
|
||||
#
|
||||
echo 'Preparing and downloading packages we need...'; echo
|
||||
if [ "${SKIP_APT:-0}" != 1 ]; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install \
|
||||
build-essential \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libncurses5-dev \
|
||||
libncursesw5-dev \
|
||||
libsqlite3-dev
|
||||
fi
|
||||
|
||||
# Check if binary is installed. Setup for build if it is not
|
||||
#
|
||||
if [ ! -x "${SERVICE_BIN}" ]; then
|
||||
echo "Binary not installed, building..."; echo
|
||||
if ! cargo --version; then
|
||||
echo "cargo not installed/working."
|
||||
echo "Install Rust (see http://rustup.us) first."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
if ! cargo test; then
|
||||
echo "test failed. Try to run the following manually for more info"
|
||||
echo "RUST_TEST_THREADS=1 cargo test --verbose"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
if ! cargo build --release; then
|
||||
echo "Server build failed."
|
||||
echo "RUST_TEST_THREADS=1 cargo build --release --verbose"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
sudo install -m 755 target/release/moonfire-nvr ${SERVICE_BIN}
|
||||
if [ -x "${SERVICE_BIN}" ]; then
|
||||
echo "Binary installed..."; echo
|
||||
else
|
||||
echo "Build failed to install..."; echo
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -d "${LIB_DIR}/ui" ]; then
|
||||
echo "UI directory doesn't exist, building..."; echo
|
||||
if ! yarn --version; then
|
||||
echo "yarn not installed/working."
|
||||
echo "Install from https://yarnpkg.com/ first."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
if ! yarn; then
|
||||
echo "UI package installation failed."
|
||||
exit 1
|
||||
fi
|
||||
if ! yarn build; then
|
||||
echo "UI build failed."
|
||||
exit 1
|
||||
fi
|
||||
sudo mkdir "${LIB_DIR}"
|
||||
sudo cp -R ui-dist "${LIB_DIR}/ui"
|
||||
fi
|
||||
|
||||
# Create user and groups
|
||||
#
|
||||
echo 'Create user/group and directories we need...'; echo
|
||||
sudo addgroup --quiet --system ${NVR_GROUP}
|
||||
sudo adduser --quiet --system ${NVR_USER} --ingroup "${NVR_GROUP}" --home "${NVR_HOME}"
|
||||
if [ ! -d "${NVR_HOME}" ]; then
|
||||
sudo mkdir "${NVR_HOME}"
|
||||
fi
|
||||
sudo chown ${NVR_USER}:${NVR_GROUP} "${NVR_HOME}"
|
||||
|
||||
# Prepare samples directory
|
||||
#
|
||||
if [ -z "${SAMPLES_DIR}" ]; then
|
||||
SAMPLES_PATH="${NVR_HOME}/${SAMPLES_DIR_NAME}"
|
||||
if [ ! -d "${SAMPLES_PATH}" ]; then
|
||||
sudo -u ${NVR_USER} -H mkdir "${SAMPLES_PATH}"
|
||||
else
|
||||
chown -R ${NVR_USER}.${NVR_USER} "${SAMPLES_PATH}"
|
||||
fi
|
||||
else
|
||||
SAMPLES_PATH="${SAMPLES_DIR}"
|
||||
if [ ! -d "${SAMPLES_PATH}" ]; then
|
||||
sudo mkdir "${SAMPLES_PATH}"
|
||||
echo ">>> Do not forget to edit /etc/fstab to mount samples media"; echo
|
||||
fi
|
||||
chown -R ${NVR_USER}.${NVR_USER} "${SAMPLES_PATH}"
|
||||
fi
|
||||
|
||||
|
||||
# Prepare for sqlite directory and set schema into db
|
||||
#
|
||||
echo 'Create database...'; echo
|
||||
if [ ! -d "${DB_DIR}" ]; then
|
||||
sudo -u ${NVR_USER} -H mkdir "${DB_DIR}"
|
||||
fi
|
||||
sudo -u ${NVR_USER} -H ${SERVICE_BIN} init --db-dir="${DB_DIR}"
|
||||
|
||||
# Prepare service files
|
||||
#
|
||||
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 \\
|
||||
--sample-file-dir=${SAMPLES_PATH} \\
|
||||
--db-dir=${DB_DIR} \\
|
||||
--ui-dir=${LIB_DIR}/ui \\
|
||||
--http-addr=0.0.0.0:${NVR_PORT}
|
||||
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-abnormal
|
||||
CPUAccounting=true
|
||||
MemoryAccounting=true
|
||||
BlockIOAccounting=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
NVR_EOF
|
||||
|
||||
# Configure and start service
|
||||
#
|
||||
if [ -f "${SERVICE_PATH}" ]; then
|
||||
echo 'Configuring system daemon...'; echo
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ${SERVICE_NAME}
|
||||
sudo systemctl restart ${SERVICE_NAME}
|
||||
echo 'Getting system daemon status...'; echo
|
||||
sudo systemctl status ${SERVICE_NAME}
|
||||
fi
|
|
@ -0,0 +1,123 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-17 Scott Lamb <slamb@slamb.org>
|
||||
#
|
||||
# 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 "Option -$OPTARG requires an argument." >&2
|
||||
exit 1
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Setup cargo if files are present
|
||||
#
|
||||
initCargo
|
||||
|
||||
# Check environment
|
||||
#
|
||||
|
||||
rv=$(getVersion rustc 0.0)
|
||||
if ! versionAtLeast "$rv" "$RUSTC_MIN_VERSION"; then
|
||||
echo "rustc not present or version less than $RUSTC_MIN_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cv=$(getVersion cargo 0.0)
|
||||
if ! versionAtLeast "$cv" "$CARGO_MIN_VERSION"; then
|
||||
echo "cargo not present or version less than $CARGO_MIN_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
yv=$(getVersion yarn 0.0)
|
||||
if ! versionAtLeast "$yv" "$YARN_MIN_VERSION"; then
|
||||
echo "yarn not present or version less than $YARN_MIN_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Building main server component
|
||||
#
|
||||
if [ "${FORCE_CLEAN:-0}" -eq 1 ]; then
|
||||
echo "Forcing clean server build..."; echo
|
||||
cargo clean
|
||||
fi
|
||||
|
||||
echo "Building test version..."; echo
|
||||
if ! cargo test; then
|
||||
echo "test failed."
|
||||
echo "Try to run the following manually for more info"
|
||||
echo "RUST_TEST_THREADS=1 cargo test --verbose"
|
||||
echo
|
||||
if [ "${IGNORE_TESTS:-0}" -ne 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if ! cargo build --release; then
|
||||
echo "Server/release build failed."
|
||||
echo "Try to run the following manually for more info"
|
||||
echo "RUST_TEST_THREADS=1 cargo build --release --verbose"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Building UI components
|
||||
#
|
||||
echo "Building UI components..."; echo
|
||||
if ! yarn build; then
|
||||
echo "UI build failed."
|
||||
echo "yarn build"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stop if build only is desired
|
||||
#
|
||||
if [ "${BUILD_ONLY:-0}" != 0 ]; then
|
||||
echo "Build (only) complete, exiting"; echo
|
||||
exit 0
|
||||
fi
|
||||
. `dirname ${BASH_SOURCE[0]}`/install.sh
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
rm -fr node_modules
|
|
@ -0,0 +1,139 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-17 Scott Lamb <slamb@slamb.org>
|
||||
#
|
||||
# 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 "Option -$OPTARG requires an argument." >&2
|
||||
exit 1
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
sudo install -m 755 target/release/moonfire-nvr ${SERVICE_BIN}
|
||||
if [ -x "${SERVICE_BIN}" ]; then
|
||||
echo "Server Binary installed..."; echo
|
||||
else
|
||||
echo "Server build failed to install..."; echo
|
||||
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/"
|
||||
sudo chown -R ${NVR_USER}:${NVR_GROUP} "${LIB_DIR}/ui/"
|
||||
echo "Server UI installed..."; echo
|
||||
else
|
||||
echo "Server UI failed to build or install..."; echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${NO_SERVICE:-0}" != 0 ]; then
|
||||
echo "Not configuring systemctl service. Done"; echo
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Make sure user was created
|
||||
#
|
||||
if ! userExists "${NVR_USER}"; then
|
||||
echo "NVR_USER=${NVR_USER} was not created. Do so manually"
|
||||
echo "or run the setup script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# 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 "NVR_PORT ($NVR_PORT) < 1024: priviliged ports not supported"
|
||||
exit 1
|
||||
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 \\
|
||||
--sample-file-dir=${SAMPLE_MEDIA_DIR}/${SAMPLE_FILE_DIR} \\
|
||||
--db-dir=${DB_DIR} \\
|
||||
--ui-dir=${LIB_DIR}/ui \\
|
||||
--http-addr=0.0.0.0:${NVR_PORT}
|
||||
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-abnormal
|
||||
CPUAccounting=true
|
||||
MemoryAccounting=true
|
||||
BlockIOAccounting=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
NVR_EOF
|
||||
|
||||
# Configure and start service
|
||||
#
|
||||
if [ -f "${SERVICE_PATH}" ]; then
|
||||
echo 'Configuring system daemon...'; echo
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable ${SERVICE_NAME}
|
||||
sudo systemctl restart ${SERVICE_NAME}
|
||||
echo 'Getting system daemon status...'; echo
|
||||
sudo systemctl status ${SERVICE_NAME}
|
||||
fi
|
|
@ -0,0 +1,236 @@
|
|||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-2017 Scott Lamb <slamb@slamb.org>
|
||||
#
|
||||
# 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="8"
|
||||
YARN_MIN_VERSION="1.0"
|
||||
CARGO_MIN_VERSION="0.2"
|
||||
RUSTC_MIN_VERSION="1.17"
|
||||
FFMPEG_MIN_VERSION="55.1.101"
|
||||
FFMPEG_RELEASE_VERSION="3.4"
|
||||
|
||||
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}"`/..")"
|
||||
}
|
||||
|
||||
catPrefix()
|
||||
{
|
||||
sed -e "s/^/$2/" < "$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
|
||||
SRC_DIR="$(resolvePath "$MOONFIRE_DIR/src")"
|
||||
NVR_USER="${NVR_USER:-moonfire-nvr}"
|
||||
NVR_GROUP="${NVR_GROUP:-$NVR_USER}"
|
||||
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}"
|
||||
SAMPLE_FILE_DIR="${SAMPLE_FILE_DIR:-sample}"
|
||||
SAMPLE_MEDIA_DIR="${SAMPLE_MEDIA_DIR:-$NVR_HOME}"
|
||||
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
|
||||
SAMPLE_FILE_DIR=$SAMPLE_FILE_DIR
|
||||
#SAMPLE_MEDIA_DIR=/mount/media
|
||||
SERVICE_NAME=$SERVICE_NAME
|
||||
SERVICE_DESC="$SERVICE_DESC"
|
||||
EOF_CONFIG
|
||||
echo "File prep.config newly created. Inspect and change as necessary."
|
||||
echo "When done, re-run this setup script. Currently it contains:"
|
||||
catPrefix "${MOONFIRE_DIR}/prep.config" " "
|
||||
exit 0
|
||||
else
|
||||
echo "Setting up with variables:"
|
||||
catPrefix "${MOONFIRE_DIR}/prep.config" " "
|
||||
echo ""
|
||||
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)
|
||||
}
|
||||
|
||||
groupExists()
|
||||
{
|
||||
return $(id -g "$1" >/dev/null 2>&1)
|
||||
}
|
||||
|
||||
moonfire()
|
||||
{
|
||||
case "$1" in
|
||||
start)
|
||||
sudo systemctl start "$2"
|
||||
;;
|
||||
stop)
|
||||
sudo systemctl stop "$2"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Add/update cameras in the database
|
||||
#
|
||||
# $1: path to cameras.sql file
|
||||
# $2: moonfire service name
|
||||
# $3: moonfire user name
|
||||
# $4: moonfire database path
|
||||
#
|
||||
addCameras()
|
||||
{
|
||||
local cpath="${CAMERAS_PATH:-$1}"
|
||||
if [ -r "${cpath}" ]; then
|
||||
echo 'Add cameras...'; echo
|
||||
# Before adding cameras, must stop service
|
||||
moonfire stop "${SERVICE_NAME:-$2}" >/dev/null 2>&1
|
||||
sudo -u ${NVR_USER:-$3} -H sqlite3 "${DB_PATH:-$4}" < "${cpath}"
|
||||
moonfire start "${SERVICE_NAME:-$2}" >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
echo_stderr()
|
||||
{
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
echo_warn()
|
||||
{
|
||||
echo_stderr "WARNING: $@"
|
||||
echo_stderr
|
||||
}
|
||||
|
||||
echo_fatal()
|
||||
{
|
||||
echo_stderr "ERROR: $@"
|
||||
echo_stderr
|
||||
exit 1;
|
||||
}
|
|
@ -0,0 +1,257 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is part of Moonfire NVR, a security camera network video recorder.
|
||||
# Copyright (C) 2016-2017 Scott Lamb <slamb@slamb.org>
|
||||
#
|
||||
# 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
|
||||
|
||||
|
||||
# Process command line options
|
||||
#
|
||||
while getopts ":f" opt; do
|
||||
case $opt in
|
||||
f) DONT_BUILD_FFMPEG=1
|
||||
;;
|
||||
:)
|
||||
echo_fatal "Option -$OPTARG requires an argument." >&2
|
||||
;;
|
||||
\?)
|
||||
echo_fatal "Invalid option: -$OPTARG" >&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Setup all apt packages we need
|
||||
#
|
||||
echo 'Preparing and downloading packages we need...'; echo
|
||||
PKGS="build-essential pkg-config sqlite3"
|
||||
#PKGS="$PKGS libavcodec-dev libavformat-dev libavutil-dev"
|
||||
PKGS="$PKGS libncurses5-dev libncursesw5-dev"
|
||||
PKGS="$PKGS libsqlite3-dev libssl-dev"
|
||||
|
||||
# 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 pakackes
|
||||
#
|
||||
sudo apt-get install -y $PKGS
|
||||
sudo apt-get autoremove -y
|
||||
|
||||
# Check for ffmpeg and install by building if necessary
|
||||
# This needs to be done before building moonfire so it can
|
||||
# find the right versions of the libraries.
|
||||
#
|
||||
ffv=`ffmpeg -version 2>/dev/null | extractVersion libavutil`
|
||||
ffv=${ffv:-0}
|
||||
if ! versionAtLeast "$ffv" "$FFMPEG_MIN_VERSION"; then
|
||||
if [ "${DONT_BUILD_FFMPEG:-0}" -ne 0 ]; then
|
||||
echo "ffmpeg version (${ffv}) installed is too old for moonfire."
|
||||
echo "Suggest you manually install at least version $FFMPEG_MIN_VERSION of libavutil."
|
||||
echo "ffmpeg versions 2.x and 3.x all should work."
|
||||
else
|
||||
OLDDIR=`pwd`
|
||||
cd ..
|
||||
if [ -d FFmpeg ]; then
|
||||
echo "Removing older FFmpeg directory..."; echo
|
||||
rm -fr FFmpeg
|
||||
fi
|
||||
echo "Fetching FFmpeg source..."; echo
|
||||
git clone --depth 1 -b "release/${FFMPEG_RELEASE_VERSION}" https://github.com/FFmpeg/FFmpeg.git
|
||||
cd FFmpeg
|
||||
pt=`uname -p 2>& /dev/null`
|
||||
if [ -z "${pt##*86*}" ]; then
|
||||
sudo apt-get install -y yasm
|
||||
fi
|
||||
./configure --enable-shared
|
||||
make
|
||||
sudo make install
|
||||
sudo ldconfig
|
||||
cd "$OLDDIR"
|
||||
OLDDIR=
|
||||
fi
|
||||
else
|
||||
echo "FFmpeg is already usable..."; echo
|
||||
fi
|
||||
|
||||
# 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 "Installing latest rust and cargo..."; echo
|
||||
curl https://sh.rustup.rs -sSf | sh -s - -y
|
||||
initCargo
|
||||
fi
|
||||
|
||||
cv=$(getVersion cargo "NA")
|
||||
if [ ${cv} = "NA" ]; then
|
||||
echo "Cargo is not (properly) installed, but rust is."
|
||||
echo "Suggest you install the latest rustup, or manually install cargo."
|
||||
echo "Install using: curl https://sh.rustup.rs -sSf | sh -s -y"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Now make sure we have dev environment and tools for the UI portion
|
||||
#
|
||||
echo "Installing all dependencies with yarn..."
|
||||
yarn install
|
||||
|
||||
finish()
|
||||
{
|
||||
if [ -z "${OLDDIR}" ]; then
|
||||
cd "${OLDDIR}"
|
||||
fi
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
# Create user and groups if not there
|
||||
#
|
||||
echo
|
||||
echo "Create user/group and directories we need..."; echo
|
||||
if ! groupExists "${NVR_GROUP}"; then
|
||||
sudo addgroup --quiet --system ${NVR_GROUP}
|
||||
fi
|
||||
if ! userExists "${NVR_USER}"; then
|
||||
sudo adduser --quiet --system ${NVR_USER} \
|
||||
--ingroup "${NVR_GROUP}" --home "${NVR_HOME}"
|
||||
fi
|
||||
if [ ! -d "${NVR_HOME}" ]; then
|
||||
sudo mkdir "${NVR_HOME}"
|
||||
fi
|
||||
sudo chown ${NVR_USER}:${NVR_GROUP} "${NVR_HOME}"
|
||||
|
||||
|
||||
# Correct possible timezone issues
|
||||
#
|
||||
echo "Correcting possible /etc/localtime setup issue..."; echo
|
||||
if [ ! -L /etc/localtime ] && [ -f /etc/timezone ] &&
|
||||
[ -f "/usr/share/zoneinfo/`cat /etc/timezone`" ]; then
|
||||
sudo rm /etc/localtime
|
||||
sudo ln -s /usr/share/zoneinfo/`cat /etc/timezone` /etc/localtime
|
||||
fi
|
||||
|
||||
|
||||
# Prepare for sqlite directory and set schema into db
|
||||
#
|
||||
DB_NAME=db
|
||||
DB_PATH="${DB_DIR}/${DB_NAME}"
|
||||
if [ ! -d "${DB_DIR}" ]; then
|
||||
echo 'Create database...'; echo
|
||||
sudo -u "${NVR_USER}" -H mkdir "${DB_DIR}"
|
||||
fi
|
||||
if [ ! -f "${DB_PATH}" ]; then
|
||||
sudo -u "${NVR_USER}" -H sqlite3 "${DB_PATH}" < "${SRC_DIR}/schema.sql"
|
||||
fi
|
||||
|
||||
CAMERAS_PATH="${MOONFIRE_DIR}/cameras.sql"
|
||||
if [ ! -r "${CAMERAS_PATH}" ]; then
|
||||
CAMERAS_PATH="${MOONFIRE_DIR}/../cameras.sql"
|
||||
if [ ! -r "${CAMERAS_PATH}" ]; then
|
||||
CAMERAS_PATH=
|
||||
fi
|
||||
fi
|
||||
if [ ! -z "${CAMERAS_PATH}" ]; then
|
||||
echo "Adding camera confguration to db..."; echo
|
||||
addCameras
|
||||
else
|
||||
echo_warn "No cameras auto configured. Use \"moonfire-nvr config\" to do it later..."
|
||||
fi
|
||||
|
||||
|
||||
# Make sure samples directory is ready
|
||||
#
|
||||
if [ -z "${SAMPLE_MEDIA_DIR}" ]; then
|
||||
echo "SAMPLE_MEDIA_DIR variable not configured. Check configuration."
|
||||
exit 1
|
||||
fi
|
||||
SAMPLE_FILE_PATH="${SAMPLE_MEDIA_DIR}/${SAMPLE_FILE_DIR}"
|
||||
if [ "${SAMPLE_FILE_PATH##${NVR_HOME}}" != "${SAMPLE_FILE_PATH}" ]; then
|
||||
# Under the home directory, create if not there
|
||||
if [ ! -d "${SAMPLE_FILE_PATH}" ]; then
|
||||
echo "Created samples directory: $SAMPLE_FILE_PATH"; echo
|
||||
sudo -u ${NVR_USER} -H mkdir "${SAMPLE_FILE_PATH}"
|
||||
fi
|
||||
else
|
||||
if [ ! -d "${SAMPLE_FILE_PATH}" ]; then
|
||||
read -r -d '' MSG <<-MSG1
|
||||
Samples directory $SAMPLE_FILE_PATH does not exist.
|
||||
If a mounted file system, make sure /etc/fstab is properly configured,
|
||||
and file system is mounted and directory created.
|
||||
MSG1
|
||||
echo_fatal "$MSG"
|
||||
fi
|
||||
fi
|
||||
# Make sure all sample directories and files owned by moonfire
|
||||
#
|
||||
sudo chown -R ${NVR_USER}.${NVR_USER} "${SAMPLE_FILE_PATH}"
|
||||
echo "Fix ownership of sample files..."; echo
|
||||
|
||||
|
||||
cat <<-'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
|
|
@ -9,7 +9,7 @@ module.exports = {
|
|||
path: path.resolve(__dirname, 'ui-dist')
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
rules: [
|
||||
{ test: /\.png$/, loader: "file-loader" },
|
||||
{ test: /\.css$/, loader: "style-loader!css-loader" },
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue