4 # ============LICENSE_START=======================================================
6 # ================================================================================
7 # Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
8 # ================================================================================
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 # ============LICENSE_END=========================================================
23 # #############################################################
24 # Features Directory Layout:
28 # └── <feature-name>*/
30 # │ └── <config-file>*
32 # │ └── [dependencies]/
33 # │ │ └── <dependent-jar>*
39 # └── [other-future-operations]
42 # <feature-name> directory should not have the "feature-" prefix.
43 # <config-file> preferable with "feature-" prefix.
51 # │ │ ├── logback-eelf.xml
53 # │ │ └── dependencies/
54 # │ │ │ └── ONAP-Logging-1.1.0-SNAPSHOT.jar
55 # │ │ │ └── eelf-core-1.0.0.jar
57 # │ │ └── feature-eelf-1.1.0-SNAPSHOT.jar
63 # │ └── feature-healthcheck.properties
66 # └── feature-healthcheck-1.1.0-SNAPSHOT.jar
67 # #############################################################
69 if [[ ${DEBUG} == y ]]; then
74 # The directories at play
76 LIB=${POLICY_HOME}/lib
77 CONFIG=${POLICY_HOME}/config
78 FEATURES=${POLICY_HOME}/features
80 if [[ ! ( -d "${LIB}" && -x "${LIB}" ) ]]; then
81 echo "ERROR: no ${LIB} directory"
85 if [[ ! ( -d "${CONFIG}" && -x "${CONFIG}" ) ]]; then
86 echo "ERROR: no ${CONFIG} directory"
90 if [[ ! ( -d "${FEATURES}" && -x "${FEATURES}" ) ]]; then
91 echo "ERROR: no ${FEATURES} directory"
95 # relative per Feature Directory Paths
97 FEATURE_DEPS="lib/dependencies"
98 FEATURE_LIB="lib/feature"
99 FEATURE_CONFIG="config"
100 FEATURE_INSTALL="install"
102 featureJars=$(find "${FEATURES}" -name "feature-*.jar" -type f -exec basename {} \; 2> /dev/null)
103 if [[ -z ${featureJars} ]]; then
109 # default field lengths
113 # update field lengths, if needed
114 for jar in ${featureJars} ; do
115 # get file name without 'jar' suffix
118 # remove feature prefix
119 tmp="${tmp#feature-}"
121 # get feature name by removing the version portion
122 name="${tmp%%-[0-9]*}"
124 # extract version portion of name
125 version="${tmp#${name}-}"
127 # grow the size of the name/version field, if needed
128 if (( "${#name}" > nameLength )) ; then
129 nameLength="${#name}"
131 if (( "${#version}" > versionLength )) ; then
132 versionLength="${#version}"
136 # ##########################################################
137 # usage: usage information
138 # ##########################################################
141 # print out usage information
143 Usage: features status
144 Get enabled/disabled status on all features
145 features enable <feature> ...
146 Enable the specified feature
147 features disable <feature> ...
148 Disable the specified feature
152 # ##########################################################
153 # status: dump out status information
154 # ##########################################################
157 if [[ ${DEBUG} == y ]]; then
158 echo "-- ${FUNCNAME[0]} $@ --"
162 local tmp name version status
163 local format="%-${nameLength}s %-${versionLength}s %s\n"
165 printf "${format}" "name" "version" "status"
166 printf "${format}" "----" "-------" "------"
168 for jar in ${featureJars} ; do
169 # get file name without 'jar' suffix
172 # remove feature prefix
173 tmp="${tmp#feature-}"
175 # get feature name by removing the version portion
176 name="${tmp%%-[0-9]*}"
178 # extract version portion of name
179 version="${tmp#${name}-}"
183 if [[ -e "${LIB}/${jar}" ]] ; then
186 printf "${format}" "${name}" "${version}" "${status}"
190 # ##########################################################
191 # depEnableAnalysis(featureName):
192 # reports on potential dependency conflicts
193 # featureName: name of the feature
194 # ##########################################################
195 function depEnableAnalysis()
197 if [[ ${DEBUG} == y ]]; then
198 echo "-- ${FUNCNAME[0]} $@ --"
202 local featureName="$1"
203 local featureDepJars featureDepJarPath depJarName multiVersionJars
205 if [[ -z ${featureName} ]]; then
206 echo "WARN: no feature name"
210 featureDepJars=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
211 for featureDepJarPath in ${featureDepJars}; do
212 depJarName=$(basename "${featureDepJarPath}")
214 # it could be a base jar
216 if [[ -f "${LIB}"/"${depJarName}" ]]; then
217 echo "WARN: dependency ${depJarName} already in use"
221 # it could be a link from another feature
223 if [[ -L "${LIB}"/"${depJarName}" ]]; then
227 # unadvisable if multiple versions exist
229 multiVersionJars=$(ls "${LIB}"/"${depJarName%%-[0-9]*.jar}"-*.jar 2> /dev/null)
230 if [[ -n "${multiVersionJars}" ]]; then
231 echo "WARN: other version of library ${depJarName} present: ${multiVersionJars}"
237 # ##########################################################
238 # configEnableAnalysis(featureName):
239 # reports on potential dependency conflicts
240 # featureName: name of the feature
241 # ##########################################################
242 function configEnableAnalysis()
244 if [[ ${DEBUG} == y ]]; then
245 echo "-- ${FUNCNAME[0]} $@ --"
249 local featureName="$1"
250 local featureConfigs configPath configFileName
252 if [[ -z ${featureName} ]]; then
253 echo "WARN: no feature name"
257 featureConfigs=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ 2> /dev/null)
258 for configPath in ${featureConfigs}; do
259 configFileName=$(basename "${configPath}")
260 if [[ -e "${LIB}"/"${configFileName}" ]]; then
261 echo "ERROR: a config file of the same name is already in the base: ${configFileName}"
267 # ##########################################################
268 # enableFeatureDeps(featureName):
269 # enables feature dependencies
270 # featureName: name of the feature
271 # ##########################################################
272 function enableFeatureDeps()
274 if [[ ${DEBUG} == y ]]; then
275 echo "-- ${FUNCNAME[0]} $@ --"
279 local featureName="$1"
280 local featureDeps featureDepPath depJarName
282 if [[ -z ${featureName} ]]; then
283 echo "WARN: no feature name"
287 featureDeps=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
288 for featureDepPath in ${featureDeps}; do
289 depJarName=$(basename "${featureDepPath}")
290 if [[ ! -f "${LIB}"/"${depJarName}" ]]; then
291 ln -s -f "${featureDepPath}" "${LIB}/"
296 # ##########################################################
297 # enableFeatureConfig(featureName):
298 # enables feature configuration
299 # featureName: name of the feature
300 # ##########################################################
301 function enableFeatureConfig()
303 if [[ ${DEBUG} == y ]]; then
304 echo "-- ${FUNCNAME[0]} $@ --"
308 local featureName="$1"
309 local featureConfigs featureConfigPath
311 if [[ -z ${featureName} ]]; then
312 echo "WARN: no feature name"
316 featureConfigs=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ -type f -maxdepth 1 2> /dev/null)
317 for featureConfigPath in ${featureConfigs}; do
318 ln -s -f "${featureConfigPath}" "${CONFIG}/"
322 # ##########################################################
323 # enableFeatureOp(featureName): 'enable' feature operation
324 # featureName: name of the feature
325 # ##########################################################
326 function enableFeatureOp()
328 if [[ ${DEBUG} == y ]]; then
329 echo "-- ${FUNCNAME[0]} $@ --"
333 local featureName="$1"
335 if [[ -z ${featureName} ]]; then
336 echo "WARN: no feature name"
340 enableScript="${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"/enable
341 if [[ -f ${enableScript} ]]; then
343 cd "${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"
350 # ##########################################################
351 # enableFeature(featureName, featureJar): enables a feature
352 # featureName: name of the feature
353 # featureJar: path to feature jar implementation
354 # ##########################################################
355 function enableFeature()
357 if [[ $DEBUG == y ]]; then
358 echo "-- ${FUNCNAME[0]} $@ --"
362 local featureName="$1"
363 local featureJar="$2"
365 if [[ -z ${featureName} ]]; then
366 echo "WARN: no feature name"
370 if [[ -z ${featureJar} ]]; then
371 echo "WARN: no feature jar"
375 if ! depEnableAnalysis "${featureName}"; then
379 if ! configEnableAnalysis "${featureName}"; then
383 # enable feature itself
385 ln -s -f "${featureJar}" "${LIB}/"
387 # enable dependent libraries if any
389 enableFeatureDeps "${featureName}"
391 # enable configuration
393 enableFeatureConfig "${featureName}"
395 # TODO: run feature install DB scripts if any
397 # run custom enable if any
399 enableFeatureOp "${featureName}"
402 # ##########################################################
403 # disableFeatureDeps(featureName):
404 # disables feature dependencies
405 # ##########################################################
406 function disableFeatureDeps()
408 if [[ ${DEBUG} == y ]]; then
409 echo "-- ${FUNCNAME[0]} $@ --"
413 local featureName="$1"
414 local xDepsEnabledMap featureBaseDirs aFeatureDir aFeatureName
415 local featureDeps aFeatureDep
416 local depJarPath depJarName depJarRealPath
418 if [[ -z ${featureName} ]]; then
419 echo "WARN: no feature name"
423 declare -A xDepsEnabledMap
425 featureBaseDirs=$(ls -d "${FEATURES}"/*/ 2> /dev/null)
426 for aFeatureDir in ${featureBaseDirs}; do
427 aFeatureName=$(basename "${aFeatureDir}")
428 if [[ "${aFeatureName}" == "${featureName}" ]]; then
432 depJarPaths=$(ls "${aFeatureDir}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
433 for depJarPath in ${depJarPaths}; do
434 if [[ "$?" == 0 ]] ; then
435 depJarName=$(basename "${depJarPath}")
436 xDepsEnabledMap[${depJarName}]="${depJarPath}"
441 if [[ ${DEBUG} == y ]]; then
442 echo "${!xDepsEnabledMap[@]}"
443 echo "${xDepsEnabledMap[@]}"
446 featureDeps=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DEPS}"/*.jar 2> /dev/null)
447 for aFeatureDep in ${featureDeps}; do
448 depJarName=$(basename "${aFeatureDep}")
449 if [[ -L "${LIB}"/"${depJarName}" ]]; then
450 depJarRealPath=$(readlink -f "${LIB}"/"${depJarName}")
451 if [[ "${depJarRealPath}" == "${aFeatureDep}" ]]; then
452 rm -f "${LIB}"/"${depJarName}"
454 # case there were multiple features using this library
455 # re-enable link fron an enabled feature
457 if [[ -n ${xDepsEnabledMap[${depJarName}]} ]]; then
458 ln -s -f "${xDepsEnabledMap[${depJarName}]}" "${LIB}/"
465 # ##########################################################
466 # disableFeatureConfig(featureName):
467 # disables feature configuration
468 # featureName: name of the feature
469 # ##########################################################
470 function disableFeatureConfig()
472 if [[ ${DEBUG} == y ]]; then
473 echo "-- ${FUNCNAME[0]} $@ --"
477 local featureName="$1"
478 local featureConfigs featureConfigPath
480 if [[ -z ${featureName} ]]; then
481 echo "WARN: no feature name"
485 featureConfigs=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_CONFIG}"/ -type f -maxdepth 1 2> /dev/null)
486 for featureConfigPath in ${featureConfigs}; do
487 configFileName=$(basename "${featureConfigPath}")
488 rm -f "${CONFIG}"/"${configFileName}" 2> /dev/null
492 # ##########################################################
493 # disableFeatureOp(featureName): 'enable' feature operation
494 # featureName: name of the feature
495 # ##########################################################
496 function disableFeatureOp()
498 if [[ ${DEBUG} == y ]]; then
499 echo "-- ${FUNCNAME[0]} $@ --"
503 local featureName="$1"
505 if [[ -z ${featureName} ]]; then
506 echo "WARN: no feature name"
510 disableScript="${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"/disable
511 if [[ -f ${disableScript} ]]; then
513 cd "${FEATURES}"/"${featureName}"/"${FEATURE_INSTALL}"
520 # ##########################################################
521 # disableFeature(featureName, featureJar): enables a feature
522 # featureName: name of the feature
523 # ##########################################################
524 function disableFeature()
526 if [[ ${DEBUG} == y ]]; then
527 echo "-- ${FUNCNAME[0]} $@ --"
531 local featureName="$1"
533 if [[ -z ${featureName} ]]; then
534 echo "WARN: no feature name"
538 # disable feature itself
542 rm -f feature-"${featureName}"-[0-9]*.jar 2> /dev/null
545 # disable dependencies if any
547 disableFeatureDeps "${featureName}"
549 # disable configuration if any
551 disableFeatureConfig "${featureName}"
553 # run feature uninstall DB scripts if any
556 # run custom disable if any
557 disableFeatureOp "${featureName}"
563 # dump out status information
569 if [[ -f "${POLICY_HOME}"/PID ]]; then
570 echo "ERROR: enable: not allowed when policy is running .."
576 # enable the specified options
579 for name in "$@" ; do
580 # look for matches - 'file' has the full path name
581 file=$(ls "${FEATURES}"/"${name}"/"${FEATURE_LIB}"/feature-"${name}"-[0-9]*.jar 2> /dev/null)
582 if [[ "$?" != 0 ]] ; then
584 echo "${name}: no such option"
586 # make sure there is only one feature jar
587 countFeatureJars=$(echo "${file}" | wc -w)
588 if [[ ${countFeatureJars} != 1 ]]; then
589 echo "WARNING: skipping ${name}, ${countFeatureJars} feature libraries found"
593 # found a match (handle multiple matches, just in case)
596 enableFeature "${name}" "${file}"
599 if [[ "${match}" ]] ; then
607 if [[ -f "${POLICY_HOME}"/PID ]]; then
608 echo "ERROR: disable: not allowed when policy is running .."
614 # disable the specified options
617 for name in "$@" ; do
618 # look for matches -- 'file' has the last segment of the path name
619 file=$(ls "${FEATURES}"/"${name}"/"${FEATURE_LIB}"/feature-"${name}"-[0-9]*.jar 2> /dev/null)
620 if [[ "$?" != 0 ]] ; then
621 echo "${name}: no such option"
623 # found a match (handle multiple matches, just in case)
626 disableFeature "${name}"
629 if [[ "${match}" ]] ; then