-
Notifications
You must be signed in to change notification settings - Fork 64
/
newrelic-install.sh
executable file
·2049 lines (1817 loc) · 60.4 KB
/
newrelic-install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#! /bin/sh
#
# Copyright 2020 New Relic Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
#
# New Relic agent installation script.
#
: ${nrversion:="UNSET"}
#
# This must run as root.
#
myuid=`id -u 2>/dev/null`
if [ "${myuid}" != "0" ]; then
echo "ERROR: $0 must be run as root" >&2
exit 1
fi
if [ -n "${NR_INSTALL_SHELL}" -a -z "${NR_KSH_EXECED}" ]; then
[ -x "${NR_INSTALL_SHELL}" ] && NR_KSH_EXECED=1 exec "${NR_INSTALL_SHELL}" -c $0 "$@"
fi
if [ -n "${BASH_VERSION}" ]; then
case $BASH_VERSION in
[3456789].* ) NR_KSH_EXECED=1 ;;
esac
fi
if [ -z "${NR_INSTALL_NOKSH}" -a -z "${NR_KSH_EXECED}" ]; then
[ -x /bin/bash ] && NR_KSH_EXECED=1 exec /bin/bash $0 "$@"
[ -x /usr/bin/bash ] && NR_KSH_EXECED=1 exec /usr/bin/bash $0 "$@"
[ -x /bin/ksh ] && NR_KSH_EXECED=1 exec /bin/ksh $0 "$@"
[ -x /usr/bin/ksh ] && NR_KSH_EXECED=1 exec /usr/bin/ksh $0 "$@"
fi
LANG=
nl='
'
#
# Determine how to suppress newlines in echo statements.
#
if echo ' \c' | grep 'c' > /dev/null 2>&1; then
en='-n'
ec=
else
en=
ec='\c'
fi
#
# Important: if this script is being invoked on a system where a package
# manager such as rpm or dpkg did the installation, the script lives in the
# shared scripts directory, and is exec'ed from that location by a front-end
# script in /usr/bin. If invoked directly out of a tar distribution it will
# not have been execed this way and we need to look in the current location
# for the scripts and agents directories. In the first case (rpm etc) the
# front end script will have set the NR_INSTALL_LOCATION environment variable
# to point to the installed location. If this variable is not set, we need
# to compute it later on. However, we always keep a variable called ispkg
# set to a non-empty string if we were invoked by the front-end script.
# Thus, in the code below, please be aware that this is what ispkg means.
#
ispkg=
[ -n "${NR_INSTALL_LOCATION}" ] && ispkg=1
imode=
if [ -n "$1" ]; then
[ "$1" = "install" ] && imode=$1
[ "$1" = "install_daemon" ] && imode=$1
[ "$1" = "uninstall" ] && imode=$1
[ "$1" = "purge" ] && imode=$1
fi
if [ -n "${NR_INSTALL_SILENT}" ]; then
if [ -z "$imode" ]; then
echo "ERROR: must invoke with either 'install', 'install_daemon' or 'uninstall' in silent mode." >&2
exit 1
fi
fi
#
# Set up the logging environment.
#
nritemp=`date +%Y%m%d-%H%M%S 2> /dev/null`
nritemp="${nritemp}-$$"
nrilog=/tmp/nrinstall-${nritemp}.log
nrsysinfo=/tmp/nrinstall-${nritemp}.sysinfo
logtar=/tmp/nrinstall-${nritemp}.tar
now=`date 2>/dev/null`
#
# Clean up any existing files.
#
rm -f $nrilog $nrsysinfo $logtar > /dev/null 2>&1
#
# Create the log file.
#
echo "New Relic Agent Install Log dated: $now" > $nrilog
#
# And the sysinfo file.
#
echo "New Relic Agent Install sysinfo dated: $now" > $nrsysinfo
#
# Set up enough of the error handling environment so we can error out
# in the event we don't support the O/S we're on.
#
error() {
echo "ERROR: $@" >> $nrilog
echo "ERROR: $@" >&2
}
#
# Get the OS type.
#
ostype=
if [ -f /etc/redhat-release -o -f /etc/redhat_version ]; then
ostype=rhel
elif [ -f /etc/os-release ] && grep -q -i 'Debian' /etc/os-release; then
ostype=debian
elif [ -f /etc/alpine-release ] || [ -d /etc/apk ]; then
ostype=alpine
elif [ -f /etc/release ]; then
if grep Solaris /etc/release > /dev/null 2>&1; then
ostype=solaris
fi
fi
if [ -z "${ostype}" ]; then
tus=`uname -s 2> /dev/null`
case "${tus}" in
[Dd][Aa][Rr][Ww][Ii][Nn]) ostype=unsupported_os ;;
[Ff][Rr][Ee][Ee][Bb][Ss][Dd]) ostype=unsupported_os ;;
[Ss][Uu][Nn][Oo][Ss]) ostype=unsupported_os ;;
[Ss][Mm][Aa][Rr][Tt][Oo][Ss]) ostype=unsupported_os ;;
esac
fi
: ${ostype:=generic}
#
# Bail out if we don't support the operating system we are on.
#
# If New Relic doesn't release anything for the O/S we are on,
# the only reason why we would have gotten here is if the user
# unpacked a tarball on an unsupported O/S
# and then attempted to run this shell script.
#
if [ "${ostype}" = "unsupported_os" ] ; then
msg=$(
cat << EOF
Your operating system is not supported by the New Relic PHP
agent. If you have any questions or believe you reached this
message in error, please file a ticket with New Relic support.
Please visit:
https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/php-agent-compatibility-requirements/
to view compatibilty requirements for the the New Relic PHP agent.
The install will now exit.
EOF
)
error "${msg}"
exit 1
fi
#
# We need to determine where we were invoked from. We use this to calculate our
# default paths for where we look for things. This makes the whole New Relic
# package relocatable.
#
: ${PATH_SEPARATOR:=':'}
if [ -z "${ispkg}" ]; then
myloc=
case "$0" in
*/*) myloc=$0 ;;
*) oIFS=$IFS
IFS=$PATH_SEPARATOR
for d in $PATH; do
IFS="${oIFS}"
[ -z "$d" ] && d="."
[ -r "$d/$0" ] && {
myloc="$d/$0"
break
}
done
IFS="${oIFS}"
;;
esac
[ -z "${myloc}" ] && myloc=$0
if [ -z "${myloc}" ]; then
echo "ERROR: existential crisis: could not find myself. Re-run with absolute path." >&2
exit 1
fi
#
# Now that we know our invocation location, we can determine the directory it
# is in. This next line is the moral equivalent of `dirname $myloc` except
# that it does not require an extra exec and relies solely on shell variable
# expansion.
#
mydir="${myloc%/*}"
#
# Not all shells track $PWD accurately so unfortunately, we cannot determine
# the absolute path without doing an exec.
#
NR_INSTALL_LOCATION=`(cd "${mydir}" 2> /dev/null; pwd 2>/dev/null)`
fi
ilibdir="${NR_INSTALL_LOCATION}"
#
# Determine the architecture we are executing on.
#
arch=`(uname -m) 2> /dev/null` || arch="unknown"
os=`(uname -s) 2> /dev/null` || os="unknown"
case "${arch}" in
aarch64 | arm64) arch=aarch64 ;;
i[3456789]86) arch=x86 ;;
*64* | *amd*) arch=x64 ;;
i86pc)
if [ "${ostype}" = "solaris" ]; then
solarch=`/usr/bin/isainfo -k 2> /dev/null`
case "$solarch" in
*64*) arch=x64 ;;
*) arch=x86 ;;
esac
else
arch=x86
fi
;;
unknown) arch=x86 ;;
esac
# allow override of detected arch
[ "${NR_INSTALL_ARCH}" = "x64" -o "${NR_INSTALL_ARCH}" = "x86_64" ] && arch="${NR_INSTALL_ARCH}"
# exit if arch is unsupported
if [ "${arch}" != "x64" ] && [ "${arch}" != "aarch64" ] ; then
msg=$(
cat << EOF
An unsupported architecture detected.
Please visit:
https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/php-agent-compatibility-requirements/
to view compatibilty requirements for the the New Relic PHP agent.
EOF
)
error "${msg}"
echo "The install will now exit."
exit 1
fi
#
# Do some sanity checking. ilibdir should contain the daemon, the agents and
# the init scripts. Ensure that is the case.
#
dmissing=
fmissing=
check_dir() {
if [ ! -d "$1" ]; then
if [ -n "$1" ]; then
dmissing="${1}${nl}${dmissing}"
fi
fi
}
check_file() {
if [ ! -f "$1" ]; then
if [ -n "$1" ]; then
fmissing="${1}${nl}${fmissing}"
fi
fi
}
xtradir=
if [ -n "${ispkg}" ]; then
daemon=/usr/bin/newrelic-daemon
else
xtradir="${ilibdir}/daemon"
daemon="${ilibdir}/daemon/newrelic-daemon.${arch}"
fi
for d in "${ilibdir}/scripts" "${ilibdir}/agent" "${xtradir}"; do
check_dir "${d}"
done
check_dir "${ilibdir}/agent/${arch}"
if [ -n "${dmissing}" ]; then
echo "ERROR: the following directories could not be found:" >&2
echo "${dmissing}" | sed -e 's/^/ /' >&2
fi
NRIUTIL="${ilibdir}/scripts/newrelic-iutil.${arch}"
[ -x "${NRIUTIL}" ] || fmissing="${NRIUTIL}${nl}${fmissing}"
if [ -z "${ispkg}" ]; then
check_file "${daemon}"
check_file "${ilibdir}/scripts/init.alpine"
check_file "${ilibdir}/scripts/init.darwin"
check_file "${ilibdir}/scripts/init.debian"
check_file "${ilibdir}/scripts/init.freebsd"
check_file "${ilibdir}/scripts/init.generic"
check_file "${ilibdir}/scripts/init.rhel"
check_file "${ilibdir}/scripts/init.solaris"
check_file "${ilibdir}/scripts/newrelic.sysconfig"
check_file "${ilibdir}/scripts/newrelic.cfg.template"
check_file "${ilibdir}/scripts/newrelic.xml"
check_file "${ilibdir}/scripts/newrelic-php5.logrotate"
check_file "${ilibdir}/scripts/newrelic-daemon.logrotate"
fi
check_file "${ilibdir}/scripts/newrelic.ini.template"
# Check that exxtension artifacts exist for all supported PHP versions
# MAKE SURE TO UPDATE THIS LIST WHENEVER SUPPORT IS ADDED OR REMOVED
# FOR A PHP VERSION
# Currently supported versions:
# (7.2, 7.3, 7.4)
# for x64
if [ ${arch} = x64 ]; then
for pmv in "20170718" "20180731" "20190902"; do
check_file "${ilibdir}/agent/${arch}/newrelic-${pmv}.so"
done
fi
# Currently supported versions:
# (8.0, 8.1, 8.2, 8.3)
# for x64 and aarch64
if [ ${arch} = x64 ] || [ ${arch} = aarch64 ]; then
for pmv in "20200930" "20210902" "20220829" "20230831"; do
check_file "${ilibdir}/agent/${arch}/newrelic-${pmv}.so"
done
fi
if [ -n "${fmissing}" ]; then
echo "ERROR: the following files could not be found:" >&2
echo "${fmissing}" | sed -e 's/^/ /' >&1
fi
if [ -n "${dmissing}" -o -n "${fmissing}" ]; then
cat <<EOF
The New Relic installation directory is incomplete. The files or
directories listed above could not be found. This usually means that
you have a corrupt installation archive. Please re-download your New
Relic software and try again. If the problem persists, please contact
${bold}https://support.newrelic.com${rmso} and report the issue. Be sure
to include all the above output in your bug report. We apologize for the
inconvenience.
EOF
exit 1
fi
#
# Here is the authoritative list of environment variables that affect this
# script. Any time these change you MUST also update the installation FAQ,
# but try to only ever add to this list, don't change the semantic meaning
# of any of these variables, or remove any of them.
#
# NR_INSTALL_NOKSH
# If set to anything non-empty, will prevent the installation script from
# attempting to re-exec itself under ksh. It only does so if it finds ksh
# in /bin or /usr/bin but if you know for sure you have a capable shell and
# your ksh isn't the original AST ksh or isn't 100% AST ksh93p or later
# compatible, then set this and hope that /bin/sh is a capable shell, or
# force re-execution with a shell of your choice by using the
# NR_INSTALL_SHELL variable described below.
#
# NR_INSTALL_SHELL
# This script assumes some basic ksh behavior. In particular it relies on
# The #,%,## and %% variable expansion operators. If your shell does not
# support these, and you do not have the official ksh93p or later installed
# as /bin/ksh or /usr/bin/ksh, then you can set this to point to a shell
# which is suitably compatible. Both bash and zsh are known to work. This
# option almost never needs to be set but is provided for automated install
# environments such as Puppet to fine-tune the behavior of this script.
# Setting this will override any attempts to automatically find ksh and
# will force the script to re-exec itself with the specified shell, if it
# exists and is executable.
#
# NR_INSTALL_PHPLIST
# Colon-separated list of directories that contain PHP installations.
# This must be the "bin" directory and contain either the CLI PHP or
# php-config. Setting this will override the computed list of PHP
# directories. As an alternative to setting this, you can also set
# the NR_INSTALL_PATH variable. See below.
#
# NR_INSTALL_PATH
# Colon-separated list of elements to add to the script's PATH. Any
# duplicate directories in this list will be ignored and will not
# change the position of any PATH elements. If NR_INSTALL_PHPLIST is not
# set then the script will look for all PHP installations on the union
# of the original PATH and this variable.
#
# NR_INSTALL_SILENT
# If set to any non-empty value, makes the install script totally silent
# and will not prompt the user for anything. This is most useful for
# automated installations via tools like Puppet.
#
# NR_INSTALL_ARCH
# If not empty MUST be one of x64. This overrides the attempt to
# detect the architecture on which the installation is taking place. This
# needs to be accurate. If you are installing on a 64-bit system this MUST
# be set to x64 so that the script can correctly check for whether or not
# your PHP is 64-bit or 32-bit.
#
# NR_INSTALL_KEY
# If this is set, it must be set to a valid New Relic license key, and this
# key will be set in the daemon config file.
#
# NR_INSTALL_INITSCRIPT
# If set this must be the name under which the init script will be installed.
# This is usually something like /etc/init.d/newrelic-daemon. If no value is
# set this will default to /etc/init.d/newrelic-daemon on all systems except
# OpenSolaris, on which it will be called /etc/init.d/newrelic.
#
# NR_INSTALL_DAEMONPATH
# If set overrides the default daemon install location. Must be set to the
# full path (including newrelic-daemon at the end).
#
# NR_INSTALL_USE_CP_NOT_LN
# If set to any non-empty value, copy the agent and don't create a symlink.
#
#
# This script will put the log file and the sysinfo file into a tar file so
# it is ready to send to New Relic support if anything goes amiss.
#
cleanup() {
(cd /tmp
tar cf "${logtar}" nrinstall-${nritemp}.log nrinstall-${nritemp}.sysinfo > /dev/null 2>&1)
rm -f ${nrilog} ${nrsysinfo} > /dev/null 2>&1
}
trap cleanup EXIT
echo "NRVERSION: ${nrversion}" >> $nrsysinfo
echo "NRVERSION: ${nrversion}" >> $nrilog
#
# Gather system information and store it in the sysinfo file.
#
echo "NR_INSTALL_LOCATION: ${NR_INSTALL_LOCATION}" >> $nrsysinfo
if [ "${arch}" = "x86" ]; then
msg=$(
cat << EOF
An unsupported architecture detected.
Please visit:
https://docs.newrelic.com/docs/apm/agents/php-agent/getting-started/php-agent-compatibility-requirements/
to view compatibilty requirements for the the New Relic PHP agent.
The install will now exit.
EOF
)
error "${msg}"
exit 1
fi
echo "ARCH: ${arch}" >> $nrsysinfo
nruname=`uname -a 2>/dev/null`
echo "UNAME: $nruname" >> $nrsysinfo
env | sort | sed -e 's/^/ENV: /' >> $nrsysinfo
if [ -z "${ispkg}" ]; then
#
# If yum is installed, list the installed packages.
#
if [ -x /usr/bin/yum ]; then
/usr/bin/yum list -q 2> /dev/null | sed -n -e '/installed$/ {s/^/YUM: /;s/[ ]*installed$//;p}' >> $nrsysinfo
fi
#
# If dpkg is installed, list the installed packages.
#
if [ -x /usr/bin/dpkg-query ]; then
/usr/bin/dpkg-query -W -f 'DPKG: ${Package} ${Version} ${Architecture}\n' >> $nrsysinfo 2>/dev/null
fi
fi
fatal() {
echo "FATAL: $@" >> $nrilog
echo "FATAL: $@" >&2
cat >&2 <<EOF
FATAL: New Relic agent installation failed.
Please contact ${bold}https://support.newrelic.com${rmso}
and report the above error. We have also created a tar file with
log files and other system info that can help solve the problem.
If the file $logtar exists please attach it to your bug report.
We apologize for the inconvenience.
EOF
exit 1
}
log() {
echo "$@" >> $nrilog
}
logcmd() {
echo "Executing: $@" >> $nrilog
"$@" >> $nrilog 2>&1
ret=$?
echo "Command returned: $ret" >> $nrilog
return $ret
}
#
# Add the specified element to the PATH. When invoked from an installation
# package the PATH is frequently restricted. We therefore want to add a few
# common elements to the PATH for when we search for PHP installations.
#
add_to_path() {
case "${PATH}" in
$1:*) ;;
*:$1) ;;
*:$1:*) ;;
*) [ -d "$1" ] && PATH="${PATH}${PATH_SEPARATOR}$1" ;;
esac
}
add_to_path /usr/local/bin
add_to_path /usr/local/php
add_to_path /usr/local/php/bin
add_to_path /usr/local/zend/bin
add_to_path /usr/local/php-7.2/bin
add_to_path /usr/local/php-7.3/bin
add_to_path /usr/local/php-7.4/bin
add_to_path /usr/local/php-8.0/bin
add_to_path /usr/local/php-8.1/bin
add_to_path /usr/local/php-8.2/bin
add_to_path /usr/local/php-8.3/bin
add_to_path /opt/local/bin
add_to_path /usr/php/bin
add_to_path /usr/php-7.2/bin
add_to_path /usr/php-7.3/bin
add_to_path /usr/php-7.4/bin
add_to_path /usr/php-8.0/bin
add_to_path /usr/php-8.1/bin
add_to_path /usr/php-8.2/bin
add_to_path /usr/php-8.3/bin
add_to_path /usr/php/7.2/bin
add_to_path /usr/php/7.3/bin
add_to_path /usr/php/7.4/bin
add_to_path /usr/php/8.0/bin
add_to_path /usr/php/8.1/bin
add_to_path /usr/php/8.2/bin
add_to_path /usr/php/8.3/bin
add_to_path /opt/php/bin
add_to_path /opt/zend/bin
add_to_path /opt/php-7.2/bin
add_to_path /opt/php-7.3/bin
add_to_path /opt/php-7.4/bin
add_to_path /opt/php-8.0/bin
add_to_path /opt/php-8.1/bin
add_to_path /opt/php-8.2/bin
add_to_path /opt/php-8.3/bin
if [ -n "${NR_INSTALL_PATH}" ]; then
oIFS="${IFS}"
IFS=$PATH_SEPARATOR
set -- $NR_INSTALL_PATH
while [ -n "$1" ]; do
add_to_path $1
shift
done
IFS="${oIFS}"
fi
log "Final PATH=$PATH"
#
# Now search along $PATH looking for PHP installations. We look for either
# php or php-config.
#
nrphplist=
oIFS="${IFS}"
IFS=${PATH_SEPARATOR}
set -- $PATH
while [ -n "$1" ]; do
pe=$1; shift
if [ -x "${pe}/php-config" -a ! -d "${pe}/php-config" ]; then
log "Found PHP in ${pe}"
nrphplist="${nrphplist}${PATH_SEPARATOR}${pe}"
nrphplist=${nrphplist#${PATH_SEPARATOR}}
elif [ -x "${pe}/php" -a ! -d "${pe}/php" ]; then
log "Found PHP in ${pe}"
nrphplist="${nrphplist}${PATH_SEPARATOR}${pe}"
nrphplist=${nrphplist#${PATH_SEPARATOR}}
else
log "No PHP found in ${pe}"
fi
done
IFS="${oIFS}"
#
# Allow the user to override the computed list of PHP installations with their
# own list. This may be useful for people deploying the agent via Puppet etc.
#
if [ -n "$NR_INSTALL_PHPLIST" ]; then
nrphplist=$NR_INSTALL_PHPLIST
fi
if [ -z "${NR_INSTALL_SILENT}" ]; then
bold=`tput bold 2> /dev/null`
rmso=`tput sgr0 2> /dev/null`
fi
#
# If we are interactive, display the banner.
#
banner() {
if [ -z "${NR_INSTALL_SILENT}" ]; then
clear
echo "${bold}New Relic PHP Agent Installation (interactive mode)${rmso}"
echo "==================================================="
echo ""
fi
}
getyn() {
prompt="$1"
valid=0
while [ $valid -eq 0 ]; do
echo ${en} "${prompt} ([y]es, [n]o or x to e[x]it): ${ec}"
read choice
case "${choice}" in
y* | Y* ) return 0 ;;
n* | N* ) return 1 ;;
x* | X* | [eE][xX][iI][tT]) exit 0 ;;
*) ;;
esac
done
}
log "Final PHP list is: $nrphplist"
#
# It is useful to know exactly how many elements are in the list so we compute
# that now.
#
if [ -z "${nrphplist}" ]; then
numphp=0
else
oIFS="$IFS"
IFS=${PATH_SEPARATOR}
set -- $nrphplist
numphp=$#
IFS="${oIFS}"
fi
choose_list() {
prompt="$1"; shift
upper=$1; shift
valid=0
chosen=
while [ $valid -eq 0 ]; do
echo ${en} "${prompt} (1-${upper}, 0 to exit): ${ec}"
read choice
case "${choice}" in
0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
*) choice= ;;
esac
if [ -n "${choice}" ]; then
if [ $choice -ge 0 -a $choice -le $upper ]; then
valid=1
fi
fi
done
chosen="${choice}"
return $choice
}
#
# If we're interactive, display the main menu.
#
if [ -z "${imode}" ]; then
banner
cat <<EOF
Please select from one of the following options:
1) Install ${bold}New Relic${rmso} Agent and Daemon
2) Uninstall ${bold}New Relic${rmso} Agent and Daemon
0) Exit
EOF
choose_list " Enter choice" 2
case ${chosen} in
0) exit 0 ;;
2) imode="uninstall" ;;
*) imode="install" ;;
esac
fi
log "Install mode: ${imode}"
#
# If we have no PHP versions in our list, exit now.
#
dodaemon=
if [ "${imode}" = "install_daemon" ] ; then
dodaemon=yes
nrphplist=
numphp=0
elif [ "${imode}" = "install" -a -z "${nrphplist}" ]; then
log "Empty PHP directory list"
if [ -z "${NR_INSTALL_SILENT}" ]; then
cat <<EOF
We searched and searched and couldn't find any complete enough PHP
installs. You may well have PHP installed on your system but are lacking
either the command line version or the php-config program that should
accompany each PHP install. Sometimes, these require that you install
the "dev" package for PHP or the "cli" version. We need one or the
other.
Please visit ${bold}https://newrelic.com/docs/php${rmso} and review the
installation documentation for ways in which you can customize this
script to look for PHP in non-standard locations or to do a manual
install.
EOF
if [ -z "${ispkg}" ]; then
if getyn " Proceed to daemon install"; then
dodaemon=yes
fi
fi
fi
if [ -z "${dodaemon}" ]; then
exit 0
fi
fi
#
# Given the list of PHP installations we have found, display a list of choices
# and allow the user to select which of the installations to work on. This is
# shared by both the install and uninstall code.
#
get_inst() {
gin=1
gioIFS="$IFS"
IFS=${PATH_SEPARATOR}
for giod in $nrphplist; do
if [ $gin -eq $1 ]; then
echo "${giod}"
break
fi
gin=$(($gin+1))
done
IFS="${gioIFS}"
}
disp_get_php_list() {
phpulist=
if [ $numphp -eq 0 ]; then
return 0
fi
if [ $numphp -eq 1 ]; then
phpulist="${nrphplist}"
return 0
fi
#
# If we're running in silent mode, install everywhere.
#
if [ -n "${NR_INSTALL_SILENT}" ]; then
phpulist="${nrphplist}"
return 0
fi
pln=0
oIFS="$IFS"
IFS=${PATH_SEPARATOR}
for d in $nrphplist; do
pln=$(($pln+1))
IFS="$oIFS"
if [ $pln -lt 10 ]; then
spaces=" "
else
spaces= " "
fi
echo " ${pln})${spaces}${d}"
done
IFS="$oIFS"
echo ""
echo " 0) Exit"
echo ""
valid=0
while [ $valid -eq 0 ]; do
echo ${en} " Selection (1-${pln}, 0 to exit or all): ${ec}"
read sel
oIFS="$IFS"
IFS=", "
if [ -n "$sel" ]; then
valid=1
for e in $sel; do
case "$e" in
0) exit 0 ;;
[Aa][Ll][Ll]) phpulist="${nrphplist}" ;;
[1-9] | [1-9][0-9] | [1-9][0-9][0-9])
if [ $e -gt $pln ]; then
valid=0
else
td=`get_inst $e`
phpulist="${phpulist}:$td"
phpulist=${phpulist#:}
fi
;;
*) valid=0 ;;
esac
done
else
valid=0
fi
IFS="$oIFS"
done
echo ""
return 0
}
set_osdifile() {
osdifile=
if [ -n "${NR_INSTALL_INITSCRIPT}" ]; then
osdifile="${NR_INSTALL_INITSCRIPT}"
fi
if [ "${ostype}" = "darwin" ]; then
: ${osdifile:=/usr/bin/newrelic-daemon-service}
elif [ "${ostype}" = "freebsd" -o -f /etc/arch-release ]; then
# It is possible that this is only for freebsd.
: ${osdifile:=/etc/rc.d/newrelic-daemon}
else
: ${osdifile:=/etc/init.d/newrelic-daemon}
fi
}
#
# With OpenSolaris on Joyent, many users have a read-only /usr
# file system. On that platform, we create (if required) and always install
# to /opt/newrelic/bin.
#
set_daemon_location() {
daemonloc=
if [ "${ostype}" = "solaris" ]; then
daemonloc=/opt/newrelic/bin/newrelic-daemon
else
daemonloc=/usr/bin/newrelic-daemon
fi
if [ -n "${NR_INSTALL_DAEMONPATH}" ]; then
daemonloc="${NR_INSTALL_DAEMONPATH}"
fi
}
#
# This code gathers into variables certain things about a particular PHP
# installation. We need this for both installing and uninstalling.
# The variables set by this function are:
#
# pi_ver
# Version number of PHP for this installation.
# pi_bin
# Path to the php executable for this installation. Can be blank.
# pi_extdir
# The PHP extension directory.
# pi_extdir2
# The directory in which the actual loadable module is to be installed,
# or the directory from which it is to be removed. pi_extdir2 can be blank
# and will be if it is the same as pi_extdir. However, if the CLI and DSO
# have different extension directories, pi_extdir2 will contain the second
# extension path. This is rare.
# pi_inifile_cli
# The global ini file for this installation. This is for the CLI version
# of PHP. This can be blank if we couldn't determine it.
# pi_inifile_dso
# The global ini file for this installation. This is for the DSO version
# that would get loaded into Apache, for example. Can be blank.
# pi_inidir_cli
# The name of a directory scanned for extra ini files. Can be empty. This
# is for the CLI version of PHP.
# pi_inidir_dso
# The name of a directory scanned for extra ini files. Can be empty. This
# is for the DSO version of PHP.
# pi_modver
# The Zend module version for this installation.
# pi_zts
# Set to "yes" if we can determine (or reasonably assume) that this PHP
# installation has Zend Thread Safety (ZTS) enabled.
# pi_incdir
# Set to the top level include directory, if it exists. Can be blank.
# pi_arch
# An attempt to guess at the architecture of the PHP installation. On MacOS
# and x86 systems this is always the same as $arch, but on x64 systems we
# may have the case where they have specifically installed or compiled a
# 32-bit version of PHP/Apache for some reason, and we need to install the
# 32-bit module not the 64-bit one. It is easy to get this wrong but we do
# the best we can. If we get it wrong, the user will need to set the
# NR_INSTALL_ARCH and NR_INSTALL_PATH to force the architecture. If
# NR_INSTALL_ARCH is set, it will always set the value of pi_arch, no matter
# what we detect.
# pi_php8
# True if PHP version is 8.0+
#
# For installation, 4 things are important:
# the extension API version, the extension load directory, and whether or not
# this version uses ZTS. These affect which version of the agent we install,
# and where. We prefer to use the CLI php for gathering this information but
# will fall back to using php-config if we must, even though it's a bit more
# complicated. The advantage of using the CLI php is that if the user has
# changed their module path with a setting, it will be reflected correctly
# whereas php-config has a static value that does not change if the user
# changes their ini file.
#
# If you are paying attention you will see the above only mentions 3 things
# we care about. The 4th is where to put the newrelic.ini fragment. This is a
# lot more complicated than we'd like. If the version of PHP being examined
# was compiled to scan an additional directory for ini files, we can safely
# put in a newrelic.ini file into that directory. If it was not compiled that
# way and only uses a single php.ini file, then we need to simply produce the
# sample newrelic.ini file and tell the user where to look for it. If only
# life was that easy.
#
# Things are further complicated by the fact that on
# many distributions, PHP is compiled twice: once for CLI and once as an
# HTTPD module or filter. They frequently have different directories that they
# scan (for example, /etc/php5/apache2 for the Apache module and /etc/php5/cli
# for the CLI version). It is common for those directories to contain a conf.d
# directory that points to a shared configuration directory, most commonly
# ../conf.d. Thus, even though the cli and the Apache modules are compiled to
# scan different directories, they both have a common directory they install
# into, and it is there that we would want to install our newrelic.ini file.
# However, there is no guarantee that there WILL be a common directory, so
# we need to check that and deal with that case, and there is no guarantee
# that there will be a directory scanned at ALL, and we need to check for that
# too.
#
# We can easily retrieve the scan directory from PHP, but the problem is
# this: we do that request using the CLI version of php. The Apache one may
# be (and most likely IS) different. We can't directly query the Apache
# directory, but in most distributions, the Apache one is compiled last, so
# the installed headers reflect the Apache scan directory and the CLI PHP
# will obviously return the CLI location.
#
# By using both methods we can make a very educated guess about these two
# directories, and check to see if they contain a "conf.d" directory that
# is a link to a shared location.
# I warned you this was more complicated than we'd like :)
#
gather_info() {
pdir="$1"
havecfg=
havebin=
pi_bin=
pi_php8=
#
# Get the path to the binary.
#
if [ -x "${pdir}/php-config" ]; then
havecfg=1
pi_bin=`${pdir}/php-config --php-binary 2> /dev/null`
if [ -z "${pi_bin}" -o ! -x "${pi_bin}" ]; then
if [ -x "${pdir}/php" ]; then
pi_bin="${pdir}/php"
fi
fi
fi
if [ -z "${pi_bin}" -a -x "${pdir}/php" ]; then
pi_bin="${pdir}/php"
fi
log "${pdir}: pi_bin=${pi_bin}"
phpi=
if [ -n "${pi_bin}" ]; then
havebin=1