misc: bug fixes and improvements for stats Fuse fs
[vpp.git] / extras / vpp_stats_fs / install.sh
1 #!/bin/bash
2
3 # Copyright (c) 2021 Cisco Systems and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # A simple script that installs stats_fs, a Fuse file system
17 # for the stats segment
18
19 set -eo pipefail
20
21 OPT_ARG=${1:-}
22
23 STATS_FS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"/
24 cd "${STATS_FS_DIR}"/../../
25 VPP_DIR=$(pwd)/
26 BUILD_ROOT=${VPP_DIR}build-root/
27 BINARY_DIR=${BUILD_ROOT}install-vpp-native/vpp/bin/
28 DEBUG_DIR=${BUILD_ROOT}install-vpp_debug-native/vpp/bin/
29 RUN_DIR=/run/vpp/
30
31 GOROOT=${GOROOT:-}
32 GOPATH=${GOPATH:-}
33
34 [ -z "${GOROOT}" ] && GOROOT="${HOME}/.go" && PATH=$GOROOT/bin:$PATH
35 [ -z "${GOPATH}" ] && GOPATH="${HOME}/go"  && PATH=$GOPATH/bin:$PATH
36
37 function install_tools() {
38   echo "Installing downloading tools"
39   apt-get update
40   apt-get install git wget curl -y
41 }
42
43 # Install latest GO version
44 function install_go() {
45   local TMP="/tmp"
46
47   echo "Installing latest GO"
48   if [[ -x "$(command -v go)" ]]; then
49     local installed_ver installed_ver_fmt
50     installed_ver=$(go version)
51     installed_ver_fmt=${installed_ver#"go version go"}
52     echo "Found installed version ${installed_ver_fmt}"
53     return
54   fi
55
56   mkdir -p "${GOROOT}"
57   mkdir -p "${GOPATH}/"{src,pkg,bin}
58
59   wget "https://dl.google.com/go/$(curl https://golang.org/VERSION?m=text).linux-amd64.tar.gz" -O "${TMP}/go.tar.gz"
60   tar -C "$GOROOT" --strip-components=1 -xzf "${TMP}/go.tar.gz"
61
62   rm -f "${TMP}/go.tar.gz"
63
64   # export path for current session to install vpp_stast_fs
65   export GOROOT=${GOROOT}
66   export PATH=$GOROOT/bin:$PATH
67   export GOPATH=$GOPATH
68   export PATH=$GOPATH/bin:$PATH
69
70   echo "Installed $(go version)"
71 }
72
73 function install_fuse() {
74   echo "Installing Fuse"
75   apt-get update
76   apt-get install fuse -y
77 }
78
79 function install_nohup() {
80   echo "Installing nohup"
81   apt-get update
82   apt-get install nohup -y
83 }
84
85 function install_go_dep() {
86   echo "Installing Go dependencies"
87   if [[ ! -x "$(command -v go)" ]]; then
88     echo "GO is not installed"
89     exit 1
90   fi
91
92   if [ ! -e "go.mod" ]; then
93     go mod init stats_fs
94     # We require a specific govpp commit for compatibility
95     go get git.fd.io/govpp.git@da95997338b77811bc2ea850db393c652b3bd18e
96     go get git.fd.io/govpp.git/adapter/statsclient@da95997338b77811bc2ea850db393c652b3bd18e
97     go get github.com/hanwen/go-fuse/v2
98   fi
99 }
100
101 # Resolve stats_fs dependencies and builds the binary
102 function build_statfs() {
103   echo "Installing statfs"
104   go build
105   if [ -d "${BINARY_DIR}" ]; then
106     mv stats_fs "${BINARY_DIR}"/stats_fs
107   elif [ -d "${DEBUG_DIR}" ]; then
108     mv stats_fs "${DEBUG_DIR}"/stats_fs
109   else
110     echo "${BINARY_DIR} and ${DEBUG_DIR} directories does not exist, the binary is installed at ${STATS_FS_DIR}stats_fs instead"
111   fi
112 }
113
114 function install_statfs() {
115   if [[ ! -x "$(command -v go)" ]]; then
116     install_tools
117     install_go
118   fi
119
120   if [[ ! -x "$(command -v fusermount)" ]]; then
121     install_fuse
122   fi
123
124   if [[ ! -x "$(command -v nohup)" ]]; then
125     install_nohup
126   fi
127
128   if [ ! -d "${STATS_FS_DIR}" ]; then
129     echo "${STATS_FS_DIR} directory does not exist"
130     exit 1
131   fi
132   cd "${STATS_FS_DIR}"
133
134   if [[ ! -x "$(command -v ${STATS_FS_DIR}stats_fs)" ]]; then
135     install_go_dep
136     build_statfs
137   else
138     echo "stats_fs already installed at path ${STATS_FS_DIR}stats_fs"
139   fi
140 }
141
142 # Starts the statfs binary
143 function start_statfs() {
144   EXE_DIR=$STATS_FS_DIR
145   if [ -d "${BINARY_DIR}" ]; then
146     EXE_DIR=$BINARY_DIR
147   elif [ -d "${DEBUG_DIR}" ]; then
148     EXE_DIR=$DEBUG_DIR
149   fi
150
151   if [[ $(pidof "${EXE_DIR}"stats_fs) ]]; then
152     echo "The service stats_fs has already been launched"
153     exit 1
154   fi
155
156   mountpoint="${RUN_DIR}stats_fs_dir"
157
158   if [[ -x "$(command -v ${EXE_DIR}stats_fs)" ]] ; then
159     if [ ! -d "$mountpoint" ] ; then
160       mkdir "$mountpoint"
161     fi
162     nohup "${EXE_DIR}"stats_fs $mountpoint 0<&- &>/dev/null &
163     return
164   fi
165
166   echo "stats_fs is not installed, use 'make stats-fs-install' first"
167   exit 1
168 }
169
170 function stop_statfs() {
171   EXE_DIR=$STATS_FS_DIR
172   if [ -d "${BINARY_DIR}" ]; then
173     EXE_DIR=$BINARY_DIR
174   elif [ -d "${DEBUG_DIR}" ]; then
175     EXE_DIR=$DEBUG_DIR
176   fi
177   if [[ ! $(pidof "${EXE_DIR}"stats_fs) ]]; then
178     echo "The service stats_fs is not running"
179     exit 1
180   fi
181
182   PID=$(pidof "${EXE_DIR}"stats_fs)
183   kill "$PID"
184   if [[ $(pidof "${EXE_DIR}"stats_fs) ]]; then
185     echo "Check your syslog file (default is /var/log/syslog)."
186     echo "It may be that the file system is busy."
187     exit 1
188   fi
189
190   if [ -d "${RUN_DIR}stats_fs_dir" ] ; then
191     rm -df "${RUN_DIR}stats_fs_dir"
192   fi
193 }
194
195 function force_unmount() {
196   if (( $(mount | grep "${RUN_DIR}stats_fs_dir" | wc -l) == 1 )) ; then
197     fusermount -uz "${RUN_DIR}stats_fs_dir"
198   else
199     echo "The default directory ${RUN_DIR}stats_fs_dir is not mounted."
200   fi
201
202   if [ -d "${RUN_DIR}stats_fs_dir" ] ; then
203     rm -df "${RUN_DIR}stats_fs_dir"
204   fi
205 }
206
207 # Remove stats_fs Go module
208 function cleanup() {
209   echo "Cleaning up stats_fs"
210   if [ ! -d "${STATS_FS_DIR}" ]; then
211     echo "${STATS_FS_DIR} directory does not exist"
212     exit 1
213   fi
214
215   cd "${STATS_FS_DIR}"
216
217   if [ -e "stats_fs" ]; then
218     rm -f stats_fs
219   fi
220
221   if [ -d "${BINARY_DIR}" ]; then
222     if [ -e "${BINARY_DIR}stats_fs" ]; then
223       rm -f ${BINARY_DIR}stats_fs
224     fi
225   elif [ -d "${DEBUG_DIR}" ]; then
226     if [ -e "${DEBUG_DIR}stats_fs" ]; then
227       rm -f ${DEBUG_DIR}stats_fs
228     fi
229   fi
230
231   if [ -d "${RUN_DIR}stats_fs_dir" ] ; then
232     rm -df "${RUN_DIR}stats_fs_dir"
233   fi
234 }
235
236 # Show available commands
237 function help() {
238   cat <<__EOF__
239   Stats-fs installer
240
241   install        - Installs requirements (Go, GoVPP, GoFUSE) and builds stats_fs
242   start          - Launches the stats_fs binary and creates a mountpoint
243   clean          - Removes stats_fs binary
244   stop           - Stops the executable, unmounts the file system
245                    and removes the mountpoint directory
246   force-unmount  - Forces the unmount of the filesystem even if it is busy
247
248 __EOF__
249 }
250
251 # Resolve chosen option and call appropriate functions
252 function resolve_option() {
253   local option=$1
254   case ${option} in
255   "start")
256     start_statfs
257     ;;
258   "install")
259     install_statfs
260     ;;
261   "clean")
262     cleanup
263     ;;
264   "unmount")
265     force_unmount
266     ;;
267   "stop")
268     stop_statfs
269     ;;
270   "help")
271     help
272     ;;
273   *) echo invalid option ;;
274   esac
275 }
276
277 if [[ -n ${OPT_ARG} ]]; then
278   resolve_option "${OPT_ARG}"
279 else
280   PS3="--> "
281   options=("install" "cleanup" "help" "start" "unmount")
282   select option in "${options[@]}"; do
283     resolve_option "${option}"
284     break
285   done
286 fi