| #!/bin/bash |
| |
| # Copyright (c) 2021 Cisco Systems and/or its affiliates. |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at: |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| # A simple script that installs stats_fs, a Fuse file system |
| # for the stats segment |
| |
| set -eo pipefail |
| |
| OPT_ARG=${1:-} |
| |
| STATS_FS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"/ |
| cd "${STATS_FS_DIR}"/../../ |
| VPP_DIR=$(pwd)/ |
| BUILD_ROOT=${VPP_DIR}build-root/ |
| BINARY_DIR=${BUILD_ROOT}install-vpp-native/vpp/bin/ |
| DEBUG_DIR=${BUILD_ROOT}install-vpp_debug-native/vpp/bin/ |
| RUN_DIR=/run/vpp/ |
| |
| GOROOT=${GOROOT:-} |
| GOPATH=${GOPATH:-} |
| |
| [ -z "${GOROOT}" ] && GOROOT="${HOME}/.go" && PATH=$GOROOT/bin:$PATH |
| [ -z "${GOPATH}" ] && GOPATH="${HOME}/go" && PATH=$GOPATH/bin:$PATH |
| |
| function install_tools() { |
| echo "Installing downloading tools" |
| apt-get update |
| apt-get install git wget curl -y |
| } |
| |
| # Install latest GO version |
| function install_go() { |
| local TMP="/tmp" |
| |
| echo "Installing latest GO" |
| if [[ -x "$(command -v go)" ]]; then |
| local installed_ver installed_ver_fmt |
| installed_ver=$(go version) |
| installed_ver_fmt=${installed_ver#"go version go"} |
| echo "Found installed version ${installed_ver_fmt}" |
| return |
| fi |
| |
| mkdir -p "${GOROOT}" |
| mkdir -p "${GOPATH}/"{src,pkg,bin} |
| |
| wget "https://dl.google.com/go/$(curl https://golang.org/VERSION?m=text).linux-amd64.tar.gz" -O "${TMP}/go.tar.gz" |
| tar -C "$GOROOT" --strip-components=1 -xzf "${TMP}/go.tar.gz" |
| |
| rm -f "${TMP}/go.tar.gz" |
| |
| # export path for current session to install vpp_stast_fs |
| export GOROOT=${GOROOT} |
| export PATH=$GOROOT/bin:$PATH |
| export GOPATH=$GOPATH |
| export PATH=$GOPATH/bin:$PATH |
| |
| echo "Installed $(go version)" |
| } |
| |
| function install_fuse() { |
| echo "Installing Fuse" |
| apt-get update |
| apt-get install fuse -y |
| } |
| |
| function install_nohup() { |
| echo "Installing nohup" |
| apt-get update |
| apt-get install nohup -y |
| } |
| |
| function install_go_dep() { |
| echo "Installing Go dependencies" |
| if [[ ! -x "$(command -v go)" ]]; then |
| echo "GO is not installed" |
| exit 1 |
| fi |
| |
| if [ ! -e "go.mod" ]; then |
| go mod init stats_fs |
| # We require a specific govpp commit for compatibility |
| go get git.fd.io/govpp.git@da95997338b77811bc2ea850db393c652b3bd18e |
| go get git.fd.io/govpp.git/adapter/statsclient@da95997338b77811bc2ea850db393c652b3bd18e |
| go get github.com/hanwen/go-fuse/v2 |
| fi |
| } |
| |
| # Resolve stats_fs dependencies and builds the binary |
| function build_statfs() { |
| echo "Installing statfs" |
| go build |
| if [ -d "${BINARY_DIR}" ]; then |
| mv stats_fs "${BINARY_DIR}"/stats_fs |
| elif [ -d "${DEBUG_DIR}" ]; then |
| mv stats_fs "${DEBUG_DIR}"/stats_fs |
| else |
| echo "${BINARY_DIR} and ${DEBUG_DIR} directories does not exist, the binary is installed at ${STATS_FS_DIR}stats_fs instead" |
| fi |
| } |
| |
| function install_statfs() { |
| if [[ ! -x "$(command -v go)" ]]; then |
| install_tools |
| install_go |
| fi |
| |
| if [[ ! -x "$(command -v fusermount)" ]]; then |
| install_fuse |
| fi |
| |
| if [[ ! -x "$(command -v nohup)" ]]; then |
| install_nohup |
| fi |
| |
| if [ ! -d "${STATS_FS_DIR}" ]; then |
| echo "${STATS_FS_DIR} directory does not exist" |
| exit 1 |
| fi |
| cd "${STATS_FS_DIR}" |
| |
| if [[ ! -x "$(command -v ${STATS_FS_DIR}stats_fs)" ]]; then |
| install_go_dep |
| build_statfs |
| else |
| echo "stats_fs already installed at path ${STATS_FS_DIR}stats_fs" |
| fi |
| } |
| |
| # Starts the statfs binary |
| function start_statfs() { |
| EXE_DIR=$STATS_FS_DIR |
| if [ -d "${BINARY_DIR}" ]; then |
| EXE_DIR=$BINARY_DIR |
| elif [ -d "${DEBUG_DIR}" ]; then |
| EXE_DIR=$DEBUG_DIR |
| fi |
| |
| if [[ $(pidof "${EXE_DIR}"stats_fs) ]]; then |
| echo "The service stats_fs has already been launched" |
| exit 1 |
| fi |
| |
| mountpoint="${RUN_DIR}stats_fs_dir" |
| |
| if [[ -x "$(command -v ${EXE_DIR}stats_fs)" ]] ; then |
| if [ ! -d "$mountpoint" ] ; then |
| mkdir "$mountpoint" |
| fi |
| nohup "${EXE_DIR}"stats_fs $mountpoint 0<&- &>/dev/null & |
| return |
| fi |
| |
| echo "stats_fs is not installed, use 'make stats-fs-install' first" |
| exit 1 |
| } |
| |
| function stop_statfs() { |
| EXE_DIR=$STATS_FS_DIR |
| if [ -d "${BINARY_DIR}" ]; then |
| EXE_DIR=$BINARY_DIR |
| elif [ -d "${DEBUG_DIR}" ]; then |
| EXE_DIR=$DEBUG_DIR |
| fi |
| if [[ ! $(pidof "${EXE_DIR}"stats_fs) ]]; then |
| echo "The service stats_fs is not running" |
| exit 1 |
| fi |
| |
| PID=$(pidof "${EXE_DIR}"stats_fs) |
| kill "$PID" |
| if [[ $(pidof "${EXE_DIR}"stats_fs) ]]; then |
| echo "Check your syslog file (default is /var/log/syslog)." |
| echo "It may be that the file system is busy." |
| exit 1 |
| fi |
| |
| if [ -d "${RUN_DIR}stats_fs_dir" ] ; then |
| rm -df "${RUN_DIR}stats_fs_dir" |
| fi |
| } |
| |
| function force_unmount() { |
| if (( $(mount | grep "${RUN_DIR}stats_fs_dir" | wc -l) == 1 )) ; then |
| fusermount -uz "${RUN_DIR}stats_fs_dir" |
| else |
| echo "The default directory ${RUN_DIR}stats_fs_dir is not mounted." |
| fi |
| |
| if [ -d "${RUN_DIR}stats_fs_dir" ] ; then |
| rm -df "${RUN_DIR}stats_fs_dir" |
| fi |
| } |
| |
| # Remove stats_fs Go module |
| function cleanup() { |
| echo "Cleaning up stats_fs" |
| if [ ! -d "${STATS_FS_DIR}" ]; then |
| echo "${STATS_FS_DIR} directory does not exist" |
| exit 1 |
| fi |
| |
| cd "${STATS_FS_DIR}" |
| |
| if [ -e "stats_fs" ]; then |
| rm -f stats_fs |
| fi |
| |
| if [ -d "${BINARY_DIR}" ]; then |
| if [ -e "${BINARY_DIR}stats_fs" ]; then |
| rm -f ${BINARY_DIR}stats_fs |
| fi |
| elif [ -d "${DEBUG_DIR}" ]; then |
| if [ -e "${DEBUG_DIR}stats_fs" ]; then |
| rm -f ${DEBUG_DIR}stats_fs |
| fi |
| fi |
| |
| if [ -d "${RUN_DIR}stats_fs_dir" ] ; then |
| rm -df "${RUN_DIR}stats_fs_dir" |
| fi |
| } |
| |
| # Show available commands |
| function help() { |
| cat <<__EOF__ |
| Stats-fs installer |
| |
| install - Installs requirements (Go, GoVPP, GoFUSE) and builds stats_fs |
| start - Launches the stats_fs binary and creates a mountpoint |
| clean - Removes stats_fs binary |
| stop - Stops the executable, unmounts the file system |
| and removes the mountpoint directory |
| force-unmount - Forces the unmount of the filesystem even if it is busy |
| |
| __EOF__ |
| } |
| |
| # Resolve chosen option and call appropriate functions |
| function resolve_option() { |
| local option=$1 |
| case ${option} in |
| "start") |
| start_statfs |
| ;; |
| "install") |
| install_statfs |
| ;; |
| "clean") |
| cleanup |
| ;; |
| "unmount") |
| force_unmount |
| ;; |
| "stop") |
| stop_statfs |
| ;; |
| "help") |
| help |
| ;; |
| *) echo invalid option ;; |
| esac |
| } |
| |
| if [[ -n ${OPT_ARG} ]]; then |
| resolve_option "${OPT_ARG}" |
| else |
| PS3="--> " |
| options=("install" "cleanup" "help" "start" "unmount") |
| select option in "${options[@]}"; do |
| resolve_option "${option}" |
| break |
| done |
| fi |