From 6aea64e3f0fb8f2316da45df26a4e0ac3dd45fec Mon Sep 17 00:00:00 2001 From: oscarsotosanchez Date: Wed, 23 Dec 2020 16:56:17 +0100 Subject: [PATCH] add openvidu aws-asg --- .../aws-asg-openvidu-server-pro/.env | 346 +++++++++++++++ .../beats/filebeat.yml | 48 +++ .../beats/metricbeat.yml | 10 + .../cluster/aws/openvidu_autodiscover.sh | 18 + .../cluster/aws/openvidu_drop.sh | 11 + .../cluster/aws/openvidu_launch_kms.sh | 69 +++ .../docker-compose.override.yml | 26 ++ .../docker-compose.yml | 167 ++++++++ .../install_openvidu_pro.sh | 398 ++++++++++++++++++ .../aws-asg-openvidu-server-pro/openvidu | 301 +++++++++++++ 10 files changed, 1394 insertions(+) create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/.env create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/filebeat.yml create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/metricbeat.yml create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_autodiscover.sh create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_drop.sh create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_launch_kms.sh create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.override.yml create mode 100644 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.yml create mode 100755 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/install_openvidu_pro.sh create mode 100755 openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/openvidu diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/.env b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/.env new file mode 100644 index 00000000..4bec679d --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/.env @@ -0,0 +1,346 @@ +# OpenVidu configuration +# ---------------------- +# Documentation: https://docs.openvidu.io/en/stable/reference-docs/openvidu-config/ + +# NOTE: This file doesn't need to quote assignment values, like most shells do. +# All values are stored as-is, even if they contain spaces, so don't quote them. + +# Domain name. If you do not have one, the public IP of the machine. +# For example: 198.51.100.1, or openvidu.example.com +DOMAIN_OR_PUBLIC_IP= + +# OpenVidu PRO License +OPENVIDU_PRO_LICENSE= + +# OpenVidu SECRET used for apps to connect to OpenVidu server and users to access to OpenVidu Dashboard +OPENVIDU_SECRET= + +# Certificate type: +# - selfsigned: Self signed certificate. Not recommended for production use. +# Users will see an ERROR when connected to web page. +# - owncert: Valid certificate purchased in a Internet services company. +# Please put the certificates files inside folder ./owncert +# with names certificate.key and certificate.cert +# - letsencrypt: Generate a new certificate using letsencrypt. Please set the +# required contact email for Let's Encrypt in LETSENCRYPT_EMAIL +# variable. +CERTIFICATE_TYPE=selfsigned + +# If CERTIFICATE_TYPE=letsencrypt, you need to configure a valid email for notifications +LETSENCRYPT_EMAIL=user@example.com + +# Proxy configuration +# If you want to change the ports on which openvidu listens, uncomment the following lines + +# Allows any request to http://DOMAIN_OR_PUBLIC_IP:HTTP_PORT/ to be automatically +# redirected to https://DOMAIN_OR_PUBLIC_IP:HTTPS_PORT/. +# WARNING: the default port 80 cannot be changed during the first boot +# if you have chosen to deploy with the option CERTIFICATE_TYPE=letsencrypt +# HTTP_PORT=80 + +# Changes the port of all services exposed by OpenVidu. +# SDKs, REST clients and browsers will have to connect to this port +# HTTPS_PORT=443 + +# Old paths are considered now deprecated, but still supported by default. +# OpenVidu Server will log a WARN message every time a deprecated path is called, indicating +# the new path that should be used instead. You can set property SUPPORT_DEPRECATED_API=false +# to stop allowing the use of old paths. +# Default value is true +# SUPPORT_DEPRECATED_API=true + +# If true request to with www will be redirected to non-www requests +# Default value is false +# REDIRECT_WWW=false + +# How many workers to configure in nginx proxy. +# The more workers, the more requests will be handled +# Default value is 10240 +# WORKER_CONNECTIONS=10240 + +# Access restrictions +# In this section you will be able to restrict the IPs from which you can access to +# Openvidu API and the Administration Panel +# WARNING! If you touch this configuration you can lose access to the platform from some IPs. +# Use it carefully. + +# This section limits access to the /dashboard (OpenVidu CE) and /inspector (OpenVidu Pro) pages. +# The form for a single IP or an IP range is: +# ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.1 and ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.0/24 +# To limit multiple IPs or IP ranges, separate by commas like this: +# ALLOWED_ACCESS_TO_DASHBOARD=198.51.100.1, 198.51.100.0/24 +# ALLOWED_ACCESS_TO_DASHBOARD= + +# This section limits access to the Openvidu REST API. +# The form for a single IP or an IP range is: +# ALLOWED_ACCESS_TO_RESTAPI=198.51.100.1 and ALLOWED_ACCESS_TO_RESTAPI=198.51.100.0/24 +# To limit multiple IPs or or IP ranges, separate by commas like this: +# ALLOWED_ACCESS_TO_RESTAPI=198.51.100.1, 198.51.100.0/24 +# ALLOWED_ACCESS_TO_RESTAPI= + +# Mode of cluster management. Can be auto (OpenVidu manages Media Nodes on its own. +# Parameter KMS_URIS is ignored) or manual (user must manage Media Nodes. Parameter +# KMS_URIS is used: if any uri is provided it must be valid) +OPENVIDU_PRO_CLUSTER_MODE=manual + +# Which environment are you using +# Possibles values: aws, on_premise +OPENVIDU_PRO_CLUSTER_ENVIRONMENT=on_premise + +# Unique identifier of your cluster. Each OpenVidu Server Pro instance corresponds to one cluster. +# You can launch as many clusters as you want with your license key. +# Cluster ID will always be stored to disk so restarting OpenVidu Server Pro will keep the same previous cluster ID +# if this configuration parameter is not given a distinct value. +# OPENVIDU_PRO_CLUSTER_ID= + +# The desired number of Media Nodes on startup. First the autodiscovery process is performed. +# If there are too many Media Nodes after that, they will be dropped until this number is reached. +# If there are not enough, more will be launched. +# This only takes place if OPENVIDU_PRO_CLUSTER_MODE is set to auto +# If set to zero no media servers will be lauched. +# Type: number >= 0 +#OPENVIDU_PRO_CLUSTER_MEDIA_NODES= + +# How often each running Media Node will send OpenVidu Server Pro Node load metrics, in seconds. +# This property is only used when OPENVIDU_PRO_CLUSTER_LOAD_STRATEGY is 'cpu'. Other load strategies +# gather information synchronously when required +# Type: number >= 0 +# OPENVIDU_PRO_CLUSTER_LOAD_INTERVAL= + +# Whether to enable or disable autoscaling. With autoscaling the number of Media Nodes will +# be automatically adjusted according to existing load +# Values: true | false +OPENVIDU_PRO_CLUSTER_AUTOSCALING=false + +# How often the autoscaling algorithm runs, in seconds +# Type number >= 0 +# OPENVIDU_PRO_CLUSTER_AUTOSCALING_INTERVAL= + +# If autoscaling is enabled, the upper limit of Media Nodes that can be reached. +# Even when the average load exceeds the threshold, no more Media Nodes will be added to cluster +# Type number >= 0 +# OPENVIDU_PRO_CLUSTER_AUTOSCALING_MAX_NODES= + +# If autoscaling is enabled, the lower limit of Media Nodes that can be reached. +# Even when the average load is inferior to the threshold, no more Media Nodes will +# be removed from the cluster +# OPENVIDU_PRO_CLUSTER_AUTOSCALING_MIN_NODES= + +# If autoscaling is enabled, the upper average load threshold that will trigger the addition +# of a new Media Node. +# Percentage value (0 min, 100 max) +# OPENVIDU_PRO_CLUSTER_AUTOSCALING_MAX_LOAD= + +# If autoscaling is enabled, the lower average load threshold that will trigger the removal +# of an existing Media Node. +# Percentage value (0 min, 100 max) +# OPENVIDU_PRO_CLUSTER_AUTOSCALING_MIN_LOAD= + +# What parameter should be used to distribute the creation of new sessions +# (and therefore distribution of load) among all available Media Nodes +OPENVIDU_PRO_CLUSTER_LOAD_STRATEGY=streams + +# Whether to enable or disable Network Quality API. You can monitor and +# warn users about the quality of their networks with this feature +# OPENVIDU_PRO_NETWORK_QUALITY=false + +# If OPENVIDU_PRO_NETWORK_QUALITY=true, how often the network quality +# algorithm will be invoked for each user, in seconds +# OPENVIDU_PRO_NETWORK_QUALITY_INTERVAL=5 + +# Max days until delete indexes in state of rollover on Elasticsearch +# Type number >= 0 +# Default Value is 15 +# OPENVIDU_PRO_ELASTICSEARCH_MAX_DAYS_DELETE= + +# If you have an external Elasticsearch and Kibana already running, put here the url to elasticsearch and kibana services. +# It is very important that both url have the port specified in the url. +# If you want to use the deployed Elasticsearch and Kibana locally, keep these variables commented. +#OPENVIDU_PRO_ELASTICSEARCH_HOST= +#OPENVIDU_PRO_KIBANA_HOST= + +# Where to store recording files. Can be 'local' (local storage) or 's3' (AWS bucket). +# You will need to define a OPENVIDU_PRO_AWS_S3_BUCKET if you use it. +#OPENVIDU_PRO_RECORDING_STORAGE= + +# S3 Bucket where to store recording files. May include paths to allow navigating +# folder structures inside the bucket. This property is only taken into account +# if OPENVIDU_PRO_RECORDING_STORAGE=s3 +#OPENVIDU_PRO_AWS_S3_BUCKET= + +# If OPENVIDU_PRO_RECORDING_STORAGE=s3, the collection of HTTP header values that the internal AWS client will use during +# the upload process. The property is a key-value map of strings, following the format of a JSON object. For example, for applying +# server-side encryption with AES-256, this header is mandatory: {"x-amz-server-side-encryption":"AES256"}. +# The list of available headers can be found here: https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/Headers.html +# This property is only taken into account if OPENVIDU_PRO_RECORDING_STORAGE=s3 +#OPENVIDU_PRO_AWS_S3_HEADERS= + +# If you're instance has a role which has access to read +# and write into the s3 bucket, you don't need this parameter +# OPENVIDU_PRO_AWS_ACCESS_KEY= + +# AWS credentials secret key from OPENVIDU_PRO_AWS_ACCESS_KEY. This property is only +# taken into account if OPENVIDU_PRO_RECORDING_STORAGE=s3 +# If you're instance has a role which has access to read +# and write into the s3 bucket, you don't need this parameter +# OPENVIDU_PRO_AWS_SECRET_KEY= + +# AWS region in which the S3 bucket is located (e.g. eu-west-1). If not provided, +# the region will try to be discovered automatically, although this is not always possible. +# This property is only taken into account if OPENVIDU_PRO_RECORDING_STORAGE=s3 +# OPENVIDU_PRO_AWS_REGION= + +# Whether to enable recording module or not +OPENVIDU_RECORDING=false + +# Use recording module with debug mode. +OPENVIDU_RECORDING_DEBUG=false + +# Openvidu Folder Record used for save the openvidu recording videos. Change it +# with the folder you want to use from your host. +OPENVIDU_RECORDING_PATH=/opt/openvidu/recordings + +# System path where OpenVidu Server should look for custom recording layouts +OPENVIDU_RECORDING_CUSTOM_LAYOUT=/opt/openvidu/custom-layout + +# if true any client can connect to +# https://OPENVIDU_SERVER_IP:OPENVIDU_PORT/recordings/any_session_file.mp4 +# and access any recorded video file. If false this path will be secured with +# OPENVIDU_SECRET param just as OpenVidu Server dashboard at +# https://OPENVIDU_SERVER_IP:OPENVIDU_PORT +# Values: true | false +OPENVIDU_RECORDING_PUBLIC_ACCESS=false + +# Which users should receive the recording events in the client side +# (recordingStarted, recordingStopped). Can be all (every user connected to +# the session), publisher_moderator (users with role 'PUBLISHER' or +# 'MODERATOR'), moderator (only users with role 'MODERATOR') or none +# (no user will receive these events) +OPENVIDU_RECORDING_NOTIFICATION=publisher_moderator + +# Timeout in seconds for recordings to automatically stop (and the session involved to be closed) +# when conditions are met: a session recording is started but no user is publishing to it or a session +# is being recorded and last user disconnects. If a user publishes within the timeout in either case, +# the automatic stop of the recording is cancelled +# 0 means no timeout +OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT=120 + +# Maximum video bandwidth sent from clients to OpenVidu Server, in kbps. +# 0 means unconstrained +OPENVIDU_STREAMS_VIDEO_MAX_RECV_BANDWIDTH=1000 + +# Minimum video bandwidth sent from clients to OpenVidu Server, in kbps. +# 0 means unconstrained +OPENVIDU_STREAMS_VIDEO_MIN_RECV_BANDWIDTH=300 + +# Maximum video bandwidth sent from OpenVidu Server to clients, in kbps. +# 0 means unconstrained +OPENVIDU_STREAMS_VIDEO_MAX_SEND_BANDWIDTH=1000 + +# Minimum video bandwidth sent from OpenVidu Server to clients, in kbps. +# 0 means unconstrained +OPENVIDU_STREAMS_VIDEO_MIN_SEND_BANDWIDTH=300 + +# All sessions of OpenVidu will try to force this codec. If OPENVIDU_STREAMS_ALLOW_TRANSCODING=true +# when a codec can not be forced, transcoding will be allowed +# Default value is VP8 +# OPENVIDU_STREAMS_FORCED_VIDEO_CODEC=VP8 + +# Allow transcoding if codec specified in OPENVIDU_STREAMS_FORCED_VIDEO_CODEC can not be applied +# Default value is false +# OPENVIDU_STREAMS_ALLOW_TRANSCODING=false + +# true to enable OpenVidu Webhook service. false' otherwise +# Values: true | false +OPENVIDU_WEBHOOK=false + +# HTTP endpoint where OpenVidu Server will send Webhook HTTP POST messages +# Must be a valid URL: http(s)://ENDPOINT +#OPENVIDU_WEBHOOK_ENDPOINT= + +# List of headers that OpenVidu Webhook service will attach to HTTP POST messages +#OPENVIDU_WEBHOOK_HEADERS= + +# List of events that will be sent by OpenVidu Webhook service +# Default value is all available events +OPENVIDU_WEBHOOK_EVENTS=[sessionCreated,sessionDestroyed,participantJoined,participantLeft,webrtcConnectionCreated,webrtcConnectionDestroyed,recordingStatusChanged,filterEventDispatched,mediaNodeStatusChanged] + +# How often the garbage collector of non active sessions runs. +# This helps cleaning up sessions that have been initialized through +# REST API (and maybe tokens have been created for them) but have had no users connected. +# Default to 900s (15 mins). 0 to disable non active sessions garbage collector +OPENVIDU_SESSIONS_GARBAGE_INTERVAL=900 + +# Minimum time in seconds that a non active session must have been in existence +# for the garbage collector of non active sessions to remove it. Default to 3600s (1 hour). +# If non active sessions garbage collector is disabled +# (property 'OPENVIDU_SESSIONS_GARBAGE_INTERVAL' to 0) this property is ignored +OPENVIDU_SESSIONS_GARBAGE_THRESHOLD=3600 + +# Call Detail Record enabled +# Whether to enable Call Detail Record or not +# Values: true | false +OPENVIDU_CDR=false + +# Path where the cdr log files are hosted +OPENVIDU_CDR_PATH=/opt/openvidu/cdr + +# Openvidu Server Level logs +# -------------------------- +# Uncomment the next line and define this variable to change +# the verbosity level of the logs of Openvidu Service +# RECOMENDED VALUES: INFO for normal logs DEBUG for more verbose logs +# OV_CE_DEBUG_LEVEL=INFO + +# OpenVidu Java Options +# -------------------------- +# Uncomment the next line and define this to add options to java command +# Documentation: https://docs.oracle.com/cd/E37116_01/install.111210/e23737/configuring_jvm.htm#OUDIG00058 +# JAVA_OPTIONS=-Xms2048m -Xmx4096m + +# ElasticSearch Java Options +# -------------------------- +# Uncomment the next line and define this to add options to java command of Elasticsearch +# Documentation: https://docs.oracle.com/cd/E37116_01/install.111210/e23737/configuring_jvm.htm#OUDIG00058 +# By default ElasticSearch is configured to use "-Xms2g -Xmx2g" as Java Min and Max memory heap allocation +# ES_JAVA_OPTS=-Xms2048m -Xmx4096m + +# Kibana And ElasticSearch Credentials Configuration +# -------------------------- +# Kibana And ElasticSearch Basic Auth configuration (Credentials) +# This credentials will aso be valid for Kibana dashboard +ELASTICSEARCH_USERNAME=elasticadmin +ELASTICSEARCH_PASSWORD= + +# Media Node Configuration +# -------------------------- +# You can add any KMS environment variable as described in the +# documentation of the docker image: https://hub.docker.com/r/kurento/kurento-media-server +# If you want to add an environment variable to KMS, you must add a variable using this prefix: 'KMS_DOCKER_ENV_', +# followed by the environment variable you want to setup. +# For example if you want to setup KMS_MIN_PORT to 50000, it would be KMS_DOCKER_ENV_KMS_MIN_PORT=50000 + +# Docker hub kurento media server: https://hub.docker.com/r/kurento/kurento-media-server +# Uncomment the next line and define this variable with KMS image that you want use +# By default, KMS_IMAGE is defined in media nodes and it does not need to be specified unless +# you want to use a specific version of KMS +# KMS_IMAGE=kurento/kurento-media-server:6.15.0 + +# Uncomment the next line and define this variable to change +# the verbosity level of the logs of KMS +# Documentation: https://doc-kurento.readthedocs.io/en/stable/features/logging.html +# KMS_DOCKER_ENV_GST_DEBUG= + +# Cloudformation configuration +# -------------------------- +# If you're working outside AWS ignore this section +#AWS_DEFAULT_REGION= +#AWS_IMAGE_ID= +#AWS_INSTANCE_TYPE= +#AWS_KEY_NAME= +#AWS_SUBNET_ID= +#AWS_SECURITY_GROUP= +#AWS_STACK_ID= +#AWS_STACK_NAME= +#AWS_CLI_DOCKER_TAG= +#AWS_VOLUME_SIZE= diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/filebeat.yml b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/filebeat.yml new file mode 100644 index 00000000..369daa45 --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/filebeat.yml @@ -0,0 +1,48 @@ +filebeat.inputs: + - type: container + paths: + - '/var/lib/docker/containers/*/*.log' + +processors: + - add_docker_metadata: + host: "unix:///var/run/docker.sock" + - add_host_metadata: + netinfo.enabled: true + + - decode_json_fields: + fields: ["message"] + target: "json" + overwrite_keys: true + - drop_event: + when.or: + - contains: + container.image.name: openvidu/openvidu-coturn + - contains: + container.image.name: docker.elastic.co/elasticsearch/elasticsearch + - contains: + container.image.name: docker.elastic.co/kibana/kibana + - contains: + container.image.name: docker.elastic.co/beats/filebeat-oss + - contains: + container.image.name: docker.elastic.co/beats/metricbeat-oss + - add_fields: + fields: + cluster-id: ${OPENVIDU_PRO_CLUSTER_ID:undefined} + +output: + elasticsearch: + hosts: ["${OPENVIDU_PRO_ELASTICSEARCH_HOST}"] + indices: + - index: "filebeat-redis-%{+yyyy.MM.dd}" + when.or: + - contains: + container.image.name: openvidu/openvidu-redis + - index: "filebeat-nginx-%{+yyyy.MM.dd}" + when.or: + - contains: + container.image.name: openvidu/openvidu-proxy + + +logging.json: true +logging.metrics.enabled: false +setup.ilm.enabled: false \ No newline at end of file diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/metricbeat.yml b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/metricbeat.yml new file mode 100644 index 00000000..09a68d9a --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/beats/metricbeat.yml @@ -0,0 +1,10 @@ +metricbeat.modules: +- module: nginx + metricsets: ["stubstatus"] + enabled: true + period: 10s + hosts: ["http://127.0.0.1"] + server_status_path: "nginx_status" +output: + elasticsearch: + hosts: ["${OPENVIDU_PRO_ELASTICSEARCH_HOST}"] diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_autodiscover.sh b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_autodiscover.sh new file mode 100644 index 00000000..8689f3b7 --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_autodiscover.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -eu -o pipefail + +# Set debug mode +DEBUG=${DEBUG:-false} +[ "$DEBUG" == "true" ] && set -x + +OUTPUT=$(mktemp -t openvidu-autodiscover-XXX --suffix .json) + +docker run --rm amazon/aws-cli:${AWS_CLI_DOCKER_TAG} ec2 describe-instances \ + --output text \ + --filters "Name=instance-state-name,Values=running" \ + "Name=tag:ov-cluster-member,Values=kms" \ + "Name=tag:ov-stack-name,Values=${AWS_STACK_NAME}" \ + "Name=tag:ov-stack-region,Values=${AWS_DEFAULT_REGION}" \ + --query 'Reservations[*].Instances[*].{id:InstanceId,ip:PrivateIpAddress}' > ${OUTPUT} + +cat ${OUTPUT} | jq --raw-input --slurp 'split("\n") | map(split("\t")) | .[0:-1] | map( { "id": .[0], "ip": .[1] } )' diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_drop.sh b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_drop.sh new file mode 100644 index 00000000..8d585480 --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_drop.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e -o pipefail + +# Set debug mode +DEBUG=${DEBUG:-false} +[ "$DEBUG" == "true" ] && set -x + +ID=$1 +[ -z "${ID}" ] && { echo "Must provide instance ID"; exit 1; } + +docker run --rm amazon/aws-cli:${AWS_CLI_DOCKER_TAG} ec2 terminate-instances --instance-ids ${ID} --output json diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_launch_kms.sh b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_launch_kms.sh new file mode 100644 index 00000000..48b92bf7 --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/cluster/aws/openvidu_launch_kms.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -e -o pipefail + +# Set debug mode +DEBUG=${DEBUG:-false} +[ "$DEBUG" == "true" ] && set -x + +TMPFILE=$(mktemp -t openvidu-userdata-XXX --suffix .txt) +OUTPUT=$(mktemp -t openvidu-launch-kms-XXX --suffix .json) +ERROUTPUT=$(mktemp -t openvidu-launch-kms-XXX --suffix .err) + +trap exit_on_error ERR + +exit_on_error () { + ERROR_TYPE=$(cat ${ERROUTPUT} | awk '{ print $4 }' | sed -r 's/\(|\)//g' | tr -d '\n') + + case ${ERROR_TYPE} + in + "InvalidParameterValue") + echo -e "Parameter invalid " $(cat ${ERROUTPUT}) >&2 + exit 1 + ;; + + "UnauthorizedOperation") + MSG_COD=$(cat ${ERROUTPUT} | awk -F: '{ print $3 }') + MSG_DEC=$(docker run --rm amazon/aws-cli:${AWS_CLI_DOCKER_TAG} sts decode-authorization-message --encoded-message ${MSG_COD}) + + echo -e "Unauthorized " $(cat ${MSG_DEC}) >&2 + exit 1 + ;; + *) + echo -e "Unknown error " $(cat ${ERROUTPUT}) >&2 + exit 1 + ;; + esac +} + +docker run --rm amazon/aws-cli:${AWS_CLI_DOCKER_TAG} ec2 run-instances \ + --image-id ${AWS_IMAGE_ID} --count 1 \ + --instance-type ${AWS_INSTANCE_TYPE} \ + --key-name ${AWS_KEY_NAME} \ + --subnet-id ${AWS_SUBNET_ID} \ + --tag-specifications "ResourceType=instance,Tags=[{Key='Name',Value='Kurento Media Server'},{Key='ov-cluster-member',Value='kms'},{Key='ov-stack-name',Value='${AWS_STACK_NAME}'},{Key='ov-stack-region',Value='${AWS_DEFAULT_REGION}'}]" \ + --iam-instance-profile Name="OpenViduInstanceProfile-${AWS_STACK_NAME}-${AWS_DEFAULT_REGION}" \ + --block-device-mappings "DeviceName=/dev/sda1,Ebs={DeleteOnTermination=True,VolumeType='gp2',VolumeSize='${AWS_VOLUME_SIZE}'}" \ + --security-group-ids ${AWS_SECURITY_GROUP} > ${OUTPUT} 2> ${ERROUTPUT} + +docker run --rm amazon/aws-cli:${AWS_CLI_DOCKER_TAG} ec2 wait instance-running --instance-ids $(cat ${OUTPUT} | jq --raw-output ' .Instances[] | .InstanceId') + +# Generating the output +KMS_IP=$(cat ${OUTPUT} | jq --raw-output ' .Instances[] | .NetworkInterfaces[0] | .PrivateIpAddress') +KMS_ID=$(cat ${OUTPUT} | jq --raw-output ' .Instances[] | .InstanceId') + +# Wait media-node controller +attempt_counter=0 +max_attempts=10 + +until $(curl --output /dev/null --silent --head --fail -u OPENVIDUAPP:${OPENVIDU_SECRET} http://${KMS_IP}:3000/media-node/status); do + if [ ${attempt_counter} -eq ${max_attempts} ];then + exit 1 + fi + attempt_counter=$(($attempt_counter+1)) + sleep 5 +done + +jq -n \ + --arg id "${KMS_ID}" \ + --arg ip "${KMS_IP}" \ + '{ id: $id, ip: $ip }' diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.override.yml b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.override.yml new file mode 100644 index 00000000..d4796d20 --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.override.yml @@ -0,0 +1,26 @@ +version: '3.1' + +services: + # -------------------------------------------------------------- + # + # Change this if your want use your own application. + # It's very important expose your application in port 5442 + # and use the http protocol. + # + # Default Application + # + # Openvidu-Call Version: 2.16.0 + # + # -------------------------------------------------------------- + app: + image: openvidu/openvidu-call:2.16.0 + restart: on-failure + network_mode: host + environment: + - SERVER_PORT=5442 + - OPENVIDU_URL=http://localhost:5443 + - OPENVIDU_SECRET=${OPENVIDU_SECRET} + - CALL_OPENVIDU_CERTTYPE=${CERTIFICATE_TYPE} + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.yml b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.yml new file mode 100644 index 00000000..791f7351 --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/docker-compose.yml @@ -0,0 +1,167 @@ +# ------------------------------------------------------------------------------ +# +# DO NOT MODIFY THIS FILE !!! +# +# Configuration properties should be specified in .env file +# +# Application based on OpenVidu should be specified in +# docker-compose.override.yml file +# +# This docker-compose file coordinates all services of OpenVidu Pro Platform +# +# This file will be overridden when update OpenVidu Platform +# +# Openvidu Version: 2.16.0 +# +# Installation Mode: On Premises +# +# ------------------------------------------------------------------------------ + +version: '3.1' + +services: + + openvidu-server: + image: openvidu/openvidu-server-pro:2.17.0-dev4 + restart: on-failure + network_mode: host + entrypoint: ['/usr/local/bin/entrypoint.sh'] + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ${OPENVIDU_RECORDING_PATH}:${OPENVIDU_RECORDING_PATH} + - ${OPENVIDU_RECORDING_CUSTOM_LAYOUT}:${OPENVIDU_RECORDING_CUSTOM_LAYOUT} + - ${OPENVIDU_CDR_PATH}:${OPENVIDU_CDR_PATH} + - ./cluster:/opt/openvidu/cluster + - .env:${PWD}/.env + env_file: + - .env + environment: + - SERVER_SSL_ENABLED=false + - SERVER_PORT=5443 + - KMS_URIS=[] + - OPENVIDU_WEBHOOK=true + - OPENVIDU_WEBHOOK_ENDPOINT=http://127.0.0.1:7777/webhook + - OPENVIDU_PRO_REPLICATION_MANAGER_WEBHOOK=https://127.0.0.1:4443/openvidu/replication-manager-webhook? + - COTURN_REDIS_IP=127.0.0.1 + - COTURN_REDIS_PASSWORD=${OPENVIDU_SECRET} + - COTURN_IP=${COTURN_IP:-auto-ipv4} + - OPENVIDU_PRO_CLUSTER=true + - OPENVIDU_PRO_KIBANA_HOST=${OPENVIDU_PRO_KIBANA_HOST:-http://127.0.0.1/kibana} + - OPENVIDU_PRO_ELASTICSEARCH_HOST=${OPENVIDU_PRO_ELASTICSEARCH_HOST:-http://127.0.0.1:9200} + - WAIT_KIBANA_URL=${OPENVIDU_PRO_KIBANA_HOST:-http://127.0.0.1/kibana} + - DOTENV_PATH=${PWD} + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" + + replication-manager: + image: openvidu/replication-manager:1.0.0-dev1 + restart: on-failure + network_mode: host + environment: + - OPENVIDU_SECRET=${OPENVIDU_SECRET} + - LOCAL_OPENVIDU_SERVER_URI=https://replication-manager:8080/ + - REDIS_HOST=127.0.0.1 + - REDIS_PORT=6379 + - REDIS_PASS=${OPENVIDU_SECRET} + - REDIS_TIMEOUT=5 + - REDIS_DB=replicationmanager + - SNS_QUEUE_NAME=ov-sns + - SQS_QUEUE_NAME=ov-sqs + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" + + redis: + image: openvidu/openvidu-redis:2.0.0-dev2 + restart: always + network_mode: host + environment: + - REDIS_PASSWORD=${OPENVIDU_SECRET} + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" + + coturn: + image: openvidu/openvidu-coturn:3.0.0-dev2 + restart: on-failure + network_mode: host + environment: + - REDIS_IP=127.0.0.1 + - TURN_LISTEN_PORT=3478 + - DB_NAME=0 + - DB_PASSWORD=${OPENVIDU_SECRET} + - MIN_PORT=40000 + - MAX_PORT=65535 + - TURN_PUBLIC_IP=${TURN_PUBLIC_IP:-auto-ipv4} + - ENABLE_COTURN_LOGS=true + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" + + nginx: + image: openvidu/openvidu-proxy:5.0.0-dev2 + restart: on-failure + network_mode: host + volumes: + - ./certificates:/etc/letsencrypt + - ./owncert:/owncert + - ./custom-nginx-vhosts:/etc/nginx/vhost.d/ + - ${OPENVIDU_RECORDING_CUSTOM_LAYOUT}:/opt/openvidu/custom-layout + environment: + - DOMAIN_OR_PUBLIC_IP=${DOMAIN_OR_PUBLIC_IP} + - CERTIFICATE_TYPE=${CERTIFICATE_TYPE} + - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} + - PROXY_HTTP_PORT=${HTTP_PORT:-} + - PROXY_HTTPS_PORT=${HTTPS_PORT:-} + - ALLOWED_ACCESS_TO_DASHBOARD=${ALLOWED_ACCESS_TO_DASHBOARD:-} + - ALLOWED_ACCESS_TO_RESTAPI=${ALLOWED_ACCESS_TO_RESTAPI:-} + - PROXY_MODE=PRO + - WITH_APP=true + - SUPPORT_DEPRECATED_API=${SUPPORT_DEPRECATED_API:-true} + - REDIRECT_WWW=${REDIRECT_WWW:-false} + - WORKER_CONNECTIONS=${WORKER_CONNECTIONS:-10240} + - PUBLIC_IP=${PROXY_PUBLIC_IP:-auto-ipv4} + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" + + metricbeat: + image: docker.elastic.co/beats/metricbeat-oss:7.8.0 + network_mode: host + restart: always + user: root + env_file: + - .env + environment: + - OPENVIDU_PRO_ELASTICSEARCH_HOST=${OPENVIDU_PRO_ELASTICSEARCH_HOST:-http://127.0.0.1:9200} + volumes: + - ./beats/metricbeat.yml:/usr/share/metricbeat/metricbeat.yml:ro + command: > + /bin/bash -c "metricbeat -e -strict.perms=false + `if [ ! -z $ELASTICSEARCH_USERNAME ]; then echo '-E output.elasticsearch.username=$ELASTICSEARCH_USERNAME'; fi` + `if [ ! -z $ELASTICSEARCH_PASSWORD ]; then echo '-E output.elasticsearch.password=$ELASTICSEARCH_PASSWORD'; fi`" + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" + + filebeat: + image: docker.elastic.co/beats/filebeat-oss:7.8.0 + network_mode: host + restart: always + user: root + env_file: + - .env + environment: + - OPENVIDU_PRO_ELASTICSEARCH_HOST=${OPENVIDU_PRO_ELASTICSEARCH_HOST:-http://127.0.0.1:9200} + volumes: + - ./beats/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro + - /var/lib/docker:/var/lib/docker:ro + - /var/run/docker.sock:/var/run/docker.sock + command: > + /bin/bash -c "filebeat -e -strict.perms=false + `if [ ! -z $ELASTICSEARCH_USERNAME ]; then echo '-E output.elasticsearch.username=$ELASTICSEARCH_USERNAME'; fi` + `if [ ! -z $ELASTICSEARCH_PASSWORD ]; then echo '-E output.elasticsearch.password=$ELASTICSEARCH_PASSWORD'; fi`" + logging: + options: + max-size: "${DOCKER_LOGS_MAX_SIZE:-100M}" diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/install_openvidu_pro.sh b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/install_openvidu_pro.sh new file mode 100755 index 00000000..eb69deaf --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/install_openvidu_pro.sh @@ -0,0 +1,398 @@ +#!/usr/bin/env bash + +# Global variables +OPENVIDU_FOLDER=openvidu +OPENVIDU_VERSION=master +OPENVIDU_UPGRADABLE_VERSION="master" +AWS_SCRIPTS_FOLDER=${OPENVIDU_FOLDER}/cluster/aws +ELASTICSEARCH_FOLDER=${OPENVIDU_FOLDER}/elasticsearch +BEATS_FOLDER=${OPENVIDU_FOLDER}/beats +DOWNLOAD_URL=https://raw.githubusercontent.com/OpenVidu/openvidu/${OPENVIDU_VERSION} + +fatal_error() { + printf "\n =======¡ERROR!=======" + printf "\n %s" "$1" + printf "\n" + exit 0 +} + +new_ov_installation() { + printf '\n' + printf '\n =======================================' + printf '\n Install Openvidu PRO %s' "${OPENVIDU_VERSION}" + printf '\n =======================================' + printf '\n' + + # Create folder openvidu-docker-compose + printf '\n => Creating folder '%s'...' "${OPENVIDU_FOLDER}" + mkdir "${OPENVIDU_FOLDER}" || fatal_error "Error while creating the folder '${OPENVIDU_FOLDER}'" + + # Create aws scripts folder + printf "\n => Creating folder 'cluster/aws'..." + mkdir -p "${AWS_SCRIPTS_FOLDER}" || fatal_error "Error while creating the folder 'cluster/aws'" + + # Create beats folder + printf "\n => Creating folder 'beats'..." + mkdir -p "${BEATS_FOLDER}" || fatal_error "Error while creating the folder 'beats'" + + # Create elasticsearch folder + printf "\n => Creating folder 'elasticsearch'..." + mkdir -p "${ELASTICSEARCH_FOLDER}" || fatal_error "Error while creating the folder 'elasticsearch'" + + printf "\n => Changing permission to 'elasticsearch' folder..." + chown 1000:1000 "${ELASTICSEARCH_FOLDER}" || fatal_error "Error while changing permission to 'elasticsearch' folder" + + # Download necessary files + printf '\n => Downloading Openvidu PRO files:' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/cluster/aws/openvidu_autodiscover.sh \ + --output "${AWS_SCRIPTS_FOLDER}/openvidu_autodiscover.sh" || fatal_error "Error when downloading the file 'openvidu_autodiscover.sh'" + printf '\n - openvidu_autodiscover.sh' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/cluster/aws/openvidu_drop.sh \ + --output "${AWS_SCRIPTS_FOLDER}/openvidu_drop.sh" || fatal_error "Error when downloading the file 'openvidu_drop.sh'" + printf '\n - openvidu_drop.sh' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/cluster/aws/openvidu_launch_kms.sh \ + --output "${AWS_SCRIPTS_FOLDER}/openvidu_launch_kms.sh" || fatal_error "Error when downloading the file 'openvidu_launch_kms.sh'" + printf '\n - openvidu_launch_kms.sh' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/beats/filebeat.yml \ + --output "${BEATS_FOLDER}/filebeat.yml" || fatal_error "Error when downloading the file 'filebeat.yml'" + printf '\n - filebeat.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/beats/metricbeat.yml \ + --output "${BEATS_FOLDER}/metricbeat.yml" || fatal_error "Error when downloading the file 'metricbeat.yml'" + printf '\n - metricbeat.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/.env \ + --output "${OPENVIDU_FOLDER}/.env" || fatal_error "Error when downloading the file '.env'" + printf '\n - .env' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/docker-compose.override.yml \ + --output "${OPENVIDU_FOLDER}/docker-compose.override.yml" || fatal_error "Error when downloading the file 'docker-compose.override.yml'" + printf '\n - docker-compose.override.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/docker-compose.yml \ + --output "${OPENVIDU_FOLDER}/docker-compose.yml" || fatal_error "Error when downloading the file 'docker-compose.yml'" + printf '\n - docker-compose.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/openvidu \ + --output "${OPENVIDU_FOLDER}/openvidu" || fatal_error "Error when downloading the file 'openvidu'" + printf '\n - openvidu' + + # Add execution permissions + printf "\n => Adding permission:" + + chmod +x "${OPENVIDU_FOLDER}/openvidu" || fatal_error "Error while adding permission to 'openvidu' program" + printf '\n - openvidu' + + chmod +x "${AWS_SCRIPTS_FOLDER}/openvidu_autodiscover.sh" || fatal_error "Error while adding permission to 'openvidu_autodiscover.sh' program" + printf '\n - openvidu_autodiscover.sh' + + chmod +x "${AWS_SCRIPTS_FOLDER}/openvidu_drop.sh" || fatal_error "Error while adding permission to 'openvidu' openvidu_drop.sh" + printf '\n - openvidu_drop.sh' + + chmod +x "${AWS_SCRIPTS_FOLDER}/openvidu_launch_kms.sh" || fatal_error "Error while adding permission to 'openvidu_launch_kms.sh' program" + printf '\n - openvidu_launch_kms.sh' + + # Create own certificated folder + printf "\n => Creating folder 'owncert'..." + mkdir "${OPENVIDU_FOLDER}/owncert" || fatal_error "Error while creating the folder 'owncert'" + + # Create vhost nginx folder + printf "\n => Creating folder 'custom-nginx-vhosts'..." + mkdir "${OPENVIDU_FOLDER}/custom-nginx-vhosts" || fatal_error "Error while creating the folder 'custom-nginx-vhosts'" + + # Ready to use + printf '\n' + printf '\n' + printf '\n =======================================' + printf '\n Openvidu PRO successfully installed.' + printf '\n =======================================' + printf '\n' + printf '\n 1. Go to openvidu folder:' + printf '\n $ cd openvidu' + printf '\n' + printf '\n 2. Configure OPENVIDU_DOMAIN_OR_PUBLIC_IP, OPENVIDU_PRO_LICENSE, ' + printf '\n OPENVIDU_SECRET, and ELASTICSEARCH_PASSWORD in .env file:' + printf '\n $ nano .env' + printf '\n' + printf '\n 3. Start OpenVidu' + printf '\n $ ./openvidu start' + printf '\n' + printf "\n CAUTION: The folder 'openvidu/elasticsearch' use user and group 1000 permissions. " + printf "\n This folder is necessary for store elasticsearch data." + printf "\n For more information, check:" + printf "\n https://docs.openvidu.io/en/${OPENVIDU_VERSION//v}/openvidu-pro/deployment/on-premises/#deployment-instructions" + printf '\n' + printf '\n' + exit 0 +} + +upgrade_ov() { + # Search local Openvidu installation + printf '\n' + printf '\n ============================================' + printf '\n Search Previous Installation of Openvidu' + printf '\n ============================================' + printf '\n' + + SEARCH_IN_FOLDERS=( + "${PWD}" + "/opt/${OPENVIDU_FOLDER}" + ) + + for folder in "${SEARCH_IN_FOLDERS[@]}"; do + printf "\n => Searching in '%s' folder..." "${folder}" + + if [ -f "${folder}/docker-compose.yml" ]; then + OPENVIDU_PREVIOUS_FOLDER="${folder}" + + printf "\n => Found installation in folder '%s'" "${folder}" + break + fi + done + + [ -z "${OPENVIDU_PREVIOUS_FOLDER}" ] && fatal_error "No previous Openvidu installation found" + + # Uppgrade Openvidu + OPENVIDU_PREVIOUS_VERSION=$(grep 'Openvidu Version:' "${OPENVIDU_PREVIOUS_FOLDER}/docker-compose.yml" | awk '{ print $4 }') + [ -z "${OPENVIDU_PREVIOUS_VERSION}" ] && fatal_error "Can't find previous OpenVidu version" + + # In this point using the variable 'OPENVIDU_PREVIOUS_VERSION' we can verify if the upgrade is + # posible or not. If it is not posible launch a warning and stop the upgrade. + if [[ "${OPENVIDU_PREVIOUS_VERSION}" != "${OPENVIDU_UPGRADABLE_VERSION}."* ]]; then + fatal_error "You can't update from version ${OPENVIDU_PREVIOUS_VERSION} to ${OPENVIDU_VERSION}.\nNever upgrade across multiple major versions." + fi + + printf '\n' + printf '\n =======================================' + printf '\n Upgrade Openvidu PRO %s to %s' "${OPENVIDU_PREVIOUS_VERSION}" "${OPENVIDU_VERSION}" + printf '\n =======================================' + printf '\n' + + ROLL_BACK_FOLDER="${OPENVIDU_PREVIOUS_FOLDER}/.old-${OPENVIDU_PREVIOUS_VERSION}" + TMP_FOLDER="${OPENVIDU_PREVIOUS_FOLDER}/tmp" + ACTUAL_FOLDER="${PWD}" + USE_OV_CALL=$(grep -E '^ image: openvidu/openvidu-call:.*$' "${OPENVIDU_PREVIOUS_FOLDER}/docker-compose.override.yml" | tr -d '[:space:]') + + printf "\n Creating rollback folder '%s'..." ".old-${OPENVIDU_PREVIOUS_VERSION}" + mkdir "${ROLL_BACK_FOLDER}" || fatal_error "Error while creating the folder '.old-${OPENVIDU_PREVIOUS_VERSION}'" + + printf "\n Creating temporal folder 'tmp'..." + mkdir "${TMP_FOLDER}" || fatal_error "Error while creating the folder 'temporal'" + + # Download necessary files + printf '\n => Downloading new Openvidu PRO files:' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/cluster/aws/openvidu_autodiscover.sh \ + --output "${TMP_FOLDER}/openvidu_autodiscover.sh" || fatal_error "Error when downloading the file 'openvidu_autodiscover.sh'" + printf '\n - openvidu_autodiscover.sh' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/cluster/aws/openvidu_drop.sh \ + --output "${TMP_FOLDER}/openvidu_drop.sh" || fatal_error "Error when downloading the file 'openvidu_drop.sh'" + printf '\n - openvidu_drop.sh' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/cluster/aws/openvidu_launch_kms.sh \ + --output "${TMP_FOLDER}/openvidu_launch_kms.sh" || fatal_error "Error when downloading the file 'openvidu_launch_kms.sh'" + printf '\n - openvidu_launch_kms.sh' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/beats/filebeat.yml \ + --output "${TMP_FOLDER}/filebeat.yml" || fatal_error "Error when downloading the file 'filebeat.yml'" + printf '\n - filebeat.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/beats/metricbeat.yml \ + --output "${TMP_FOLDER}/metricbeat.yml" || fatal_error "Error when downloading the file 'metricbeat.yml'" + printf '\n - metricbeat.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/.env \ + --output "${TMP_FOLDER}/.env" || fatal_error "Error when downloading the file '.env'" + printf '\n - .env' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/docker-compose.override.yml \ + --output "${TMP_FOLDER}/docker-compose.override.yml" || fatal_error "Error when downloading the file 'docker-compose.override.yml'" + printf '\n - docker-compose.override.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/docker-compose.yml \ + --output "${TMP_FOLDER}/docker-compose.yml" || fatal_error "Error when downloading the file 'docker-compose.yml'" + printf '\n - docker-compose.yml' + + curl --silent ${DOWNLOAD_URL}/openvidu-server/deployments/pro/docker-compose/aws-as-openvidu-server-pro/openvidu \ + --output "${TMP_FOLDER}/openvidu" || fatal_error "Error when downloading the file 'openvidu'" + printf '\n - openvidu' + + # Dowloading new images and stoped actual Openvidu + printf '\n => Dowloading new images...' + printf '\n' + sleep 1 + + printf "\n => Moving to 'tmp' folder..." + printf '\n' + cd "${TMP_FOLDER}" || fatal_error "Error when moving to 'tmp' folder" + printf '\n' + docker-compose pull | true + + printf '\n => Stoping Openvidu...' + printf '\n' + sleep 1 + + printf "\n => Moving to 'openvidu' folder..." + printf '\n' + cd "${OPENVIDU_PREVIOUS_FOLDER}" || fatal_error "Error when moving to 'openvidu' folder" + printf '\n' + docker-compose down | true + + printf '\n' + printf '\n => Moving to working dir...' + cd "${ACTUAL_FOLDER}" || fatal_error "Error when moving to working dir" + + # Move old files to rollback folder + printf '\n => Moving previous installation files to rollback folder:' + + mv "${OPENVIDU_PREVIOUS_FOLDER}/docker-compose.yml" "${ROLL_BACK_FOLDER}" || fatal_error "Error while moving previous 'docker-compose.yml'" + printf '\n - docker-compose.yml' + + if [ ! -z "${USE_OV_CALL}" ]; then + mv "${OPENVIDU_PREVIOUS_FOLDER}/docker-compose.override.yml" "${ROLL_BACK_FOLDER}" || fatal_error "Error while moving previous 'docker-compose.override.yml'" + printf '\n - docker-compose.override.yml' + fi + + mv "${OPENVIDU_PREVIOUS_FOLDER}/openvidu" "${ROLL_BACK_FOLDER}" || fatal_error "Error while moving previous 'openvidu'" + printf '\n - openvidu' + + mv "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws" "${ROLL_BACK_FOLDER}" || fatal_error "Error while moving previous 'cluster/aws'" + printf '\n - cluster/aws' + + mv "${OPENVIDU_PREVIOUS_FOLDER}/beats" "${ROLL_BACK_FOLDER}" || fatal_error "Error while moving previous 'beats'" + printf '\n - beats' + + cp "${OPENVIDU_PREVIOUS_FOLDER}/.env" "${ROLL_BACK_FOLDER}" || fatal_error "Error while moving previous '.env'" + printf '\n - .env' + + if [ -d "${OPENVIDU_PREVIOUS_FOLDER}/custom-nginx-vhosts" ]; then + mv "${OPENVIDU_PREVIOUS_FOLDER}/custom-nginx-vhosts" "${ROLL_BACK_FOLDER}" || fatal_error "Error while moving previous directory 'custom-nginx-vhosts'" + printf '\n - custom-nginx-vhosts' + fi + + # Move tmp files to Openvidu + printf '\n => Updating files:' + + mv "${TMP_FOLDER}/docker-compose.yml" "${OPENVIDU_PREVIOUS_FOLDER}" || fatal_error "Error while updating 'docker-compose.yml'" + printf '\n - docker-compose.yml' + + if [ ! -z "${USE_OV_CALL}" ]; then + mv "${TMP_FOLDER}/docker-compose.override.yml" "${OPENVIDU_PREVIOUS_FOLDER}" || fatal_error "Error while updating 'docker-compose.override.yml'" + printf '\n - docker-compose.override.yml' + else + mv "${TMP_FOLDER}/docker-compose.override.yml" "${OPENVIDU_PREVIOUS_FOLDER}/docker-compose.override.yml-${OPENVIDU_VERSION}" || fatal_error "Error while updating 'docker-compose.override.yml'" + printf '\n - docker-compose.override.yml-%s' "${OPENVIDU_VERSION}" + fi + + mv "${TMP_FOLDER}/.env" "${OPENVIDU_PREVIOUS_FOLDER}/.env-${OPENVIDU_VERSION}" || fatal_error "Error while moving previous '.env'" + printf '\n - .env-%s' "${OPENVIDU_VERSION}" + + mv "${TMP_FOLDER}/openvidu" "${OPENVIDU_PREVIOUS_FOLDER}" || fatal_error "Error while updating 'openvidu'" + printf '\n - openvidu' + + mkdir "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws" || fatal_error "Error while creating the folder 'cluster/aws'" + + mkdir "${OPENVIDU_PREVIOUS_FOLDER}/beats" || fatal_error "Error while creating the folder 'beats'" + + mv "${TMP_FOLDER}/openvidu_autodiscover.sh" "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws" || fatal_error "Error while updating 'openvidu_autodiscover.sh'" + printf '\n - openvidu_autodiscover.sh' + + mv "${TMP_FOLDER}/openvidu_drop.sh" "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws" || fatal_error "Error while updating 'openvidu_drop.sh'" + printf '\n - openvidu_drop.sh' + + mv "${TMP_FOLDER}/openvidu_launch_kms.sh" "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws" || fatal_error "Error while updating 'openvidu_launch_kms.sh'" + printf '\n - openvidu_launch_kms.sh' + + mv "${TMP_FOLDER}/filebeat.yml" "${OPENVIDU_PREVIOUS_FOLDER}/beats/filebeat.yml" || fatal_error "Error while updating 'filebeat.yml'" + printf '\n - filebeat.yml' + + mv "${TMP_FOLDER}/metricbeat.yml" "${OPENVIDU_PREVIOUS_FOLDER}/beats/metricbeat.yml" || fatal_error "Error while updating 'metricbeat.yml'" + printf '\n - metricbeat.yml' + + printf "\n => Deleting 'tmp' folder" + rm -rf "${TMP_FOLDER}" || fatal_error "Error deleting 'tmp' folder" + + # Add execution permissions + printf "\n => Adding permission to 'openvidu' program..." + + chmod +x "${OPENVIDU_PREVIOUS_FOLDER}/openvidu" || fatal_error "Error while adding permission to 'openvidu' program" + printf '\n - openvidu' + + chmod +x "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws/openvidu_autodiscover.sh" || fatal_error "Error while adding permission to 'openvidu_autodiscover.sh' program" + printf '\n - openvidu_autodiscover.sh' + + chmod +x "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws/openvidu_drop.sh" || fatal_error "Error while adding permission to 'openvidu' openvidu_drop.sh" + printf '\n - openvidu_drop.sh' + + chmod +x "${OPENVIDU_PREVIOUS_FOLDER}/cluster/aws/openvidu_launch_kms.sh" || fatal_error "Error while adding permission to 'openvidu_launch_kms.sh' program" + printf '\n - openvidu_launch_kms.sh' + + # Define old mode: On Premise or Cloud Formation + OLD_MODE=$(grep -E "Installation Mode:.*$" "${ROLL_BACK_FOLDER}/docker-compose.yml" | awk '{ print $4,$5 }') + [ ! -z "${OLD_MODE}" ] && sed -i -r "s/Installation Mode:.+/Installation Mode: ${OLD_MODE}/" "${OPENVIDU_PREVIOUS_FOLDER}/docker-compose.yml" + + # In Aws, update AMI ID + AWS_REGION=$(grep -E "AWS_DEFAULT_REGION=.*$" "${OPENVIDU_PREVIOUS_FOLDER}/.env" | cut -d'=' -f2) + if [[ ! -z ${AWS_REGION} ]]; then + NEW_AMI_ID=$(curl https://s3-eu-west-1.amazonaws.com/aws.openvidu.io/CF-OpenVidu-Pro-${OPENVIDU_VERSION//v}.yaml --silent | + sed -n -e '/KMSAMIMAP:/,/Metadata:/ p' | + grep -A 1 ${AWS_REGION} | grep AMI | tr -d " " | cut -d":" -f2) + [[ -z ${NEW_AMI_ID} ]] && fatal_error "Error while getting new AWS_IMAGE_ID for Media Nodes" + sed -i "s/.*AWS_IMAGE_ID=.*/AWS_IMAGE_ID=${NEW_AMI_ID}/" "${OPENVIDU_PREVIOUS_FOLDER}/.env" || fatal_error "Error while updating new AWS_IMAGE_ID for Media Nodes" + fi + + + # Ready to use + printf '\n' + printf '\n' + printf '\n ================================================' + printf "\n Openvidu successfully upgraded to version %s" "${OPENVIDU_VERSION}" + printf '\n ================================================' + printf '\n' + printf "\n 1. A new file 'docker-compose.yml' has been created with the new OpenVidu %s services" "${OPENVIDU_VERSION}" + printf '\n' + printf "\n 2. The previous file '.env' remains intact, but a new file '.env-%s' has been created." "${OPENVIDU_VERSION}" + printf "\n Transfer any configuration you wish to keep in the upgraded version from '.env' to '.env-%s'." "${OPENVIDU_VERSION}" + printf "\n When you are OK with it, rename and leave as the only '.env' file of the folder the new '.env-%s'." "${OPENVIDU_VERSION}" + printf '\n' + printf "\n 3. If you were using Openvidu Call application, it has been automatically updated in file 'docker-compose.override.yml'." + printf "\n However, if you were using your own application, a file called 'docker-compose.override.yml-%s'" "${OPENVIDU_VERSION}" + printf "\n has been created with the latest version of Openvidu Call. If you don't plan to use it you can delete it." + printf '\n' + printf '\n 4. Start new version of Openvidu' + printf '\n $ ./openvidu start' + printf '\n' + printf "\n If you want to rollback, all the files from the previous installation have been copied to folder '.old-%s'" "${OPENVIDU_PREVIOUS_VERSION}" + printf '\n' + printf '\n' + printf '\n' +} + +# Check docker and docker-compose installation +if ! command -v docker > /dev/null; then + echo "You don't have docker installed, please install it and re-run the command" + exit 0 +fi + +if ! command -v docker-compose > /dev/null; then + echo "You don't have docker-compose installed, please install it and re-run the command" + exit 0 +else + COMPOSE_VERSION=$(docker-compose version --short | sed "s/-rc[0-9]*//") + if ! printf '%s\n%s\n' "1.24" "$COMPOSE_VERSION" | sort -V -C; then + echo "You need a docker-compose version equal or higher than 1.24, please update your docker-compose and re-run the command"; \ + exit 0 + fi +fi + +# Check type of installation +if [[ ! -z "$1" && "$1" == "upgrade" ]]; then + upgrade_ov +else + new_ov_installation +fi diff --git a/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/openvidu b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/openvidu new file mode 100755 index 00000000..b4229d5a --- /dev/null +++ b/openvidu-server/deployments/pro/docker-compose/aws-asg-openvidu-server-pro/openvidu @@ -0,0 +1,301 @@ +#!/bin/bash + +upgrade_ov() { + UPGRADE_SCRIPT_URL="https://s3-eu-west-1.amazonaws.com/aws.openvidu.io/install_openvidu_pro_OVVERSION.sh" + HTTP_STATUS=$(curl -s -o /dev/null -I -w "%{http_code}" ${UPGRADE_SCRIPT_URL//OVVERSION/$1}) + + printf " => Upgrading Openvidu PRO to '%s' version" "$1" + + if [ "$HTTP_STATUS" == "200" ]; then + printf "\n => Downloading and upgrading new version" + printf "\n" + + curl --silent ${UPGRADE_SCRIPT_URL//OVVERSION/$1} | bash -s upgrade + else + printf "\n =======¡ERROR!=======" + printf "\n Openvidu PRO Version '%s' not exist" "$1" + printf "\n" + exit 0 + fi +} + +collect_basic_information() { + LINUX_VERSION=$(lsb_release -d) + DOCKER_PS=$(docker ps) + DOCKER_VERSION=$(docker version --format '{{.Server.Version}}') + DOCKER_COMPOSE_VERSION=$(docker-compose version --short) + OV_FOLDER="${PWD}" + OV_VERSION=$(grep 'Openvidu Version:' "${OV_FOLDER}/docker-compose.yml" | awk '{ print $4 }') + CONTAINERS=$(docker ps | awk '{if(NR>1) print $NF}') + + if [ ! -z "$(grep -E '^ image: openvidu/openvidu-call:.*$' "${OV_FOLDER}/docker-compose.override.yml" | tr -d '[:space:]')" ]; then + OV_CALL_VERSION=$(grep -E 'Openvidu-Call Version:' "${OV_FOLDER}/docker-compose.override.yml" | awk '{ print $4 }') + fi + [ -z "${OV_CALL_VERSION}" ] && OV_CALL_VERSION="No present" + + OV_TYPE_INSTALLATION=$(grep 'Installation Mode:' "${OV_FOLDER}/docker-compose.yml" | awk '{ print $4,$5 }') + TREE_OV_DIRECTORY=$(find "." ! -path '*/0/*' | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/") +} + +version_ov() { + collect_basic_information + + printf '\nOpenvidu Information:' + printf '\n' + printf '\n Installation Type: %s' "${OV_TYPE_INSTALLATION}" + printf '\n Openvidu Version: %s' "${OV_VERSION}" + printf '\n Openvidu Call Version: %s' "${OV_CALL_VERSION}" + printf '\n' + printf '\nSystem Information:' + printf '\n' + printf '\n Linux Version:' + printf '\n - %s' "${LINUX_VERSION}" + printf '\n Docker Version: %s' "${DOCKER_VERSION}" + printf '\n Docker Compose Version: %s' "${DOCKER_COMPOSE_VERSION}" + printf '\n' + printf '\nInstallation Information:' + printf '\n' + printf '\n Installation Folder: %s' "${OV_FOLDER}" + printf '\n Installation Folder Tree:' + printf '\n%s' "$(echo "${TREE_OV_DIRECTORY}" | sed -e 's/.//' -e ':a' -e 'N;$!ba' -e 's/\n/\n\t/g')" + printf '\n' + printf '\nDocker Running Services:' + printf '\n' + printf '\n %s' "$(echo "${DOCKER_PS}" | sed -e ':a' -e 'N;$!ba' -e 's/\n/\n\t/g')" + printf '\n' +} + +generate_report() { + collect_basic_information + + REPORT_CREATION_DATE=$(date +"%d-%m-%Y") + REPORT_CREATION_TIME=$(date +"%H:%M:%S") + REPORT_NAME="openvidu-report-${REPORT_CREATION_DATE}-$(date +"%H-%M").txt" + REPORT_OUPUT="${OV_FOLDER}/${REPORT_NAME}" + + { + printf "\n =======================================" + printf "\n = REPORT INFORMATION =" + printf "\n =======================================" + printf '\n' + printf '\n Creation Date: %s' "${REPORT_CREATION_DATE}" + printf '\n Creation Time: %s' "${REPORT_CREATION_TIME}" + printf '\n' + printf "\n =======================================" + printf "\n = OPENVIDU INFORMATION =" + printf "\n =======================================" + printf '\n' + printf '\n Installation Type: %s' "${OV_TYPE_INSTALLATION}" + printf '\n Openvidu Version: %s' "${OV_VERSION}" + printf '\n Openvidu Call Version: %s' "${OV_CALL_VERSION}" + printf '\n' + printf "\n =======================================" + printf "\n = SYSTEM INFORMATION =" + printf "\n =======================================" + printf '\n' + printf '\n Linux Version:' + printf '\n - %s' "${LINUX_VERSION}" + printf '\n Docker Version: %s' "${DOCKER_VERSION}" + printf '\n Docker Compose Version: %s' "${DOCKER_COMPOSE_VERSION}" + printf '\n' + printf "\n =======================================" + printf "\n = INSTALLATION INFORMATION =" + printf "\n =======================================" + printf '\n' + printf '\n Installation Folder: %s' "${OV_FOLDER}" + printf '\n Installation Folder Tree:' + printf '\n%s' "$(echo "${TREE_OV_DIRECTORY}" | sed -e 's/.//' -e ':a' -e 'N;$!ba' -e 's/\n/\n\t/g')" + printf '\n' + printf "\n =======================================" + printf "\n = DOCKER RUNNING SERVICES =" + printf "\n =======================================" + printf '\n' + printf '\n %s' "$(echo "${DOCKER_PS}" | sed -e ':a' -e 'N;$!ba' -e 's/\n/\n\t/g')" + printf '\n' + printf "\n =======================================" + printf "\n = CONFIGURATION FILES =" + printf "\n =======================================" + printf '\n' + printf '\n ================ .env =================' + printf '\n' + printf '\n' + + cat < "${OV_FOLDER}/.env" | sed -r -e "s/OPENVIDU_SECRET=.+/OPENVIDU_SECRET=****/" -e "s/OPENVIDU_PRO_LICENSE=.+/OPENVIDU_PRO_LICENSE=****/" -e "s/ELASTICSEARCH_PASSWORD=.+/ELASTICSEARCH_PASSWORD=****/" + + printf '\n' + printf '\n ========= docker-compose.yml ==========' + printf '\n' + printf '\n' + + cat "${OV_FOLDER}/docker-compose.yml" + + printf '\n' + printf '\n ==== docker-compose.override.yml ====' + printf '\n' + printf '\n' + + if [ -f "${OV_FOLDER}/docker-compose.override.yml" ]; then + cat < "${OV_FOLDER}/docker-compose.override.yml" + else + printf '\n The docker-compose.override.yml file is not present' + fi + + printf '\n' + printf '\n' + printf "\n =======================================" + printf "\n = LOGS =" + printf "\n =======================================" + + for CONTAINER in $CONTAINERS + do + printf '\n' + printf "\n ---------------------------------------" + printf "\n %s" $CONTAINER + printf "\n ---------------------------------------" + printf '\n' + docker logs $CONTAINER + printf "\n ---------------------------------------" + printf '\n' + printf '\n' + done + + printf "\n =======================================" + printf "\n = CONTAINER ENVS VARIABLES =" + printf "\n =======================================" + + for CONTAINER in $CONTAINERS + do + printf '\n' + printf "\n =======================================" + printf "\n %s" $CONTAINER + printf "\n ---------------------------------------" + printf '\n' + docker exec $CONTAINER env + printf "\n ---------------------------------------" + printf '\n' + printf '\n' + done + + } >> "${REPORT_OUPUT}" 2>&1 + + printf "\n Generation of the report completed with success" + printf "\n You can get your report at path '%s'" "${REPORT_OUPUT}" + printf "\n" +} + +is_external_url() { + local URL=$1 + if [[ -z "$URL" ]]; then + return 1 + fi + if [[ "${URL}" == *"localhost"* ]] || [[ "${URL}" == *"127.0.0.1"* ]] || [[ "${URL}" == *"::1"* ]]; then + return 1 + else + return 0 + fi +} + +start_openvidu() { + local RUN_LOCAL_ES + local RUN_LOCAL_KIBANA + local CONFIGURED_ELASTICSEARCH_HOST + local CONFIGURED_KIBANA_HOST + CONFIGURED_ELASTICSEARCH_HOST=$(grep -v '^#' .env | grep OPENVIDU_PRO_ELASTICSEARCH_HOST | cut -d '=' -f2) + CONFIGURED_KIBANA_HOST=$(grep -v '^#' .env | grep OPENVIDU_PRO_KIBANA_HOST | cut -d '=' -f2) + RUN_LOCAL_ES=true + RUN_LOCAL_KIBANA=true + if is_external_url "${CONFIGURED_ELASTICSEARCH_HOST}"; then + printf "Configured external elasticsearch: %s" "${CONFIGURED_ELASTICSEARCH_HOST}" + printf "\n" + RUN_LOCAL_ES=false + fi + if is_external_url "${CONFIGURED_KIBANA_HOST}"; then + printf "Configured external kibana: %s" "${CONFIGURED_KIBANA_HOST}" + printf "\n" + RUN_LOCAL_KIBANA=false + fi + docker-compose up -d \ + $(if [ "${RUN_LOCAL_ES}" == "false" ]; then echo '--scale elasticsearch=0'; fi) \ + $(if [ "${RUN_LOCAL_KIBANA}" == "false" ]; then echo '--scale kibana=0'; fi) +} + +usage() { + printf "Usage: \n\t openvidu [command]" + printf "\n\nAvailable Commands:" + printf "\n\tstart\t\t\tStart all services" + printf "\n\tstop\t\t\tStop all services" + printf "\n\trestart\t\t\tRestart all stoped and running services" + printf "\n\tlogs\t\t\tShow openvidu-server logs" + printf "\n\tupgrade\t\t\tUpgrade to the lastest Openvidu version" + printf "\n\tupgrade [version]\tUpgrade to the specific Openvidu version" + printf "\n\tversion\t\t\tShow version of Openvidu Server" + printf "\n\treport\t\t\tGenerate a report with the current status of Openvidu" + printf "\n\thelp\t\t\tShow help for openvidu command" + printf "\n" +} + +[[ -z "${FOLLOW_OPENVIDU_LOGS}" ]] && FOLLOW_OPENVIDU_LOGS=true + +case $1 in + + start) + start_openvidu + if [[ "${FOLLOW_OPENVIDU_LOGS}" == "true" ]]; then + docker-compose logs -f openvidu-server + fi + ;; + + stop) + docker-compose down + ;; + + restart) + docker-compose down + start_openvidu + if [[ "${FOLLOW_OPENVIDU_LOGS}" == "true" ]]; then + docker-compose logs -f openvidu-server + fi + ;; + + logs) + docker-compose logs -f openvidu-server + ;; + + upgrade) + if [ -z "$2" ]; then + UPGRADE_VERSION="latest" + else + UPGRADE_VERSION="$2" + fi + + read -r -p " You're about to update Openvidu PRO to '${UPGRADE_VERSION}' version. Are you sure? [y/N]: " response + case "$response" in + [yY][eE][sS]|[yY]) + upgrade_ov "${UPGRADE_VERSION}" + ;; + *) + exit 0 + ;; + esac + ;; + + version) + version_ov + ;; + + report) + read -r -p " You are about to generate a report on the current status of Openvidu, this may take some time. Do you want to continue? [y/N]: " response + case "$response" in + [yY][eE][sS]|[yY]) + generate_report + ;; + *) + exit 0 + ;; + esac + ;; + + *) + usage + ;; +esac \ No newline at end of file