Skip to content

Commit acc3701

Browse files
committed
Setup scripts for local dev
Setup scripts will assume it's in the root plugin directory of OSD and places the `scripts` folder into the OSD/scripts folder for run purposes with the following command: ``` yarn setup ``` This then will allow from the root OSD directory to run ``` yarn assistant:start ``` which will setup up the OpenSearch cluster as expected. Please note, at the time of writing this the feature/os-assistant and feature/2.11/os-assistant added the feature for installing OpenSearch assistant related plugins. Not main or 2.x. Signed-off-by: Kawika Avilla <kavilla414@gmail.com>
1 parent a5c2025 commit acc3701

File tree

6 files changed

+301
-1
lines changed

6 files changed

+301
-1
lines changed

DEVELOPER_GUIDE.md

+28
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,34 @@ Ultimately, your directory structure should look like this:
2424
│ └── dashboards-assistant
2525
```
2626

27+
Setup local stack
28+
29+
1. Export keys locally:
30+
```sh
31+
# defaults to us-west-2
32+
export REGION=
33+
export AWS_ACCESS_KEY_ID=
34+
export AWS_SECRET_ACCESS_KEY=
35+
export AWS_SESSION_TOKEN=
36+
```
37+
2. Setup OSD plugins
38+
```sh
39+
# from OSD root folder
40+
cd plugins
41+
# example with security plugin
42+
git clone --depth 1 --branch $VERSION https://github.com/opensearch-project/security-dashboards-plugin.git
43+
cd dashboards-assistant
44+
# NOTE: this will change OSD to be version 2.11.0 for dev purposes
45+
yarn setup
46+
cd ../../
47+
yarn osd bootstrap
48+
```
49+
2. Start local environment
50+
```sh
51+
# from OSD root folder
52+
yarn start:assistant
53+
```
54+
2755
### Build
2856

2957
To build the plugin's distributable zip simply run `yarn build` in the plugin's directory.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"plugin-helpers": "node ../../scripts/plugin_helpers",
1111
"prepare": "husky install",
1212
"lint:es": "node ../../scripts/eslint",
13-
"lint": "yarn lint:es"
13+
"lint": "yarn lint:es",
14+
"setup": "scripts/pre_install.sh"
1415
},
1516
"lint-staged": {
1617
"*.{ts,tsx,js,jsx}": [

scripts/assistant/add_model.sh

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
function add_model() {
5+
[ -z "$ACCESS_KEY_ID" ] && ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
6+
[ -z "$SECRET_ACCESS_KEY" ] && SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
7+
[ -z "$SESSION_TOKEN" ] && SESSION_TOKEN=${AWS_SESSION_TOKEN}
8+
9+
ENDPOINT=https://admin:${CREDENTIAL}@${BIND_ADDRESS}:${BIND_PORT}
10+
11+
curl -s -k "${ENDPOINT}/_cluster/settings" -XPUT -H 'Content-Type: application/json' -d '{
12+
"persistent" : {
13+
"plugins.ml_commons.trusted_connector_endpoints_regex":
14+
[ "^https://runtime\\.sagemaker\\..*[a-z0-9-]\\.amazonaws\\.com/.*$",
15+
"^https://api\\.openai\\.com/.*$",
16+
"^https://api\\.cohere\\.ai/.*$",
17+
"^https://bedrock-runtime\\.[a-z0-9-]+\\.amazonaws\\.com/.*$"
18+
]
19+
}
20+
}' | jq
21+
22+
# shellcheck disable=2016
23+
CONNECTOR=$(curl -s -k "${ENDPOINT}/_plugins/_ml/connectors/_create" -XPOST -H 'Content-Type: application/json' -d '{
24+
"name": "BedRock test claude Connector",
25+
"description": "The connector to BedRock service for claude model",
26+
"version": 1,
27+
"protocol": "aws_sigv4",
28+
"parameters": {
29+
"region": "'$REGION'",
30+
"service_name": "bedrock",
31+
"anthropic_version": "bedrock-2023-05-31",
32+
"endpoint": "bedrock.'$REGION'.amazonaws.com",
33+
"auth": "Sig_V4",
34+
"content_type": "application/json"
35+
},
36+
"credential": {
37+
"access_key": "'$ACCESS_KEY_ID'",
38+
"secret_key": "'$SECRET_ACCESS_KEY'",
39+
"session_token": "'$SESSION_TOKEN'"
40+
},
41+
"actions": [
42+
{
43+
"action_type": "predict",
44+
"method": "POST",
45+
"url": "https://bedrock-runtime.'"$REGION"'.amazonaws.com/model/anthropic.claude-v1/invoke",
46+
"headers": {
47+
"content-type": "application/json",
48+
"x-amz-content-sha256": "required"
49+
},
50+
"request_body": "{\"prompt\":\"${parameters.prompt}\", \"max_tokens_to_sample\":${parameters.max_tokens_to_sample}, \"temperature\":${parameters.temperature}, \"anthropic_version\":\"${parameters.anthropic_version}\" }"
51+
}
52+
]
53+
}' | jq -r '.connector_id')
54+
echo "❗connector: ${CONNECTOR}"
55+
56+
GROUP=$(curl -s -k "${ENDPOINT}/_plugins/_ml/model_groups/_register" -XPOST -H 'Content-Type: application/json' -d '{
57+
"name": "test_model_group_public",
58+
"description": "This is a public model group"
59+
}' | jq | grep -oP '(?<=ID: )(.+)(?=\.)|(?<=model_group_id": ")(.+)(?=",)' | head -n 1)
60+
echo "❗group: ${GROUP}"
61+
62+
EMBEDDINGS_TASK=$(curl -s -k "${ENDPOINT}/_plugins/_ml/models/_register?deploy=true" -XPOST -H 'Content-Type: application/json' -d '{
63+
"name": "huggingface/sentence-transformers/all-mpnet-base-v2",
64+
"version": "1.0.1",
65+
"model_group_id": "'$GROUP'",
66+
"model_format": "TORCH_SCRIPT"
67+
}' | jq -r '.task_id')
68+
echo "❗embeddings_task: ${EMBEDDINGS_TASK}"
69+
70+
MODEL=$(curl -s -k "${ENDPOINT}/_plugins/_ml/models/_register?deploy=true" -XPOST -H 'Content-Type: application/json' -d '{
71+
"name": "Claude model on bedrock",
72+
"model_group_id": "'$GROUP'",
73+
"function_name": "remote",
74+
"version": "1.0.0",
75+
"connector_id": "'$CONNECTOR'",
76+
"description": "test model"
77+
}' | jq -r '.model_id')
78+
79+
echo "❗model: ${MODEL}"
80+
sleep 40
81+
EMBEDDINGS_MODEL=$(curl -s -k "${ENDPOINT}/_plugins/_ml/tasks/${EMBEDDINGS_TASK}" | jq -r '.model_id')
82+
echo "❗embeddings_model: ${EMBEDDINGS_MODEL}"
83+
84+
curl -s -k "${ENDPOINT}/.chat-assistant-config/_doc/model-config" -XPOST -H 'Content-Type: application/json' -d '{
85+
"model_type":"claude_bedrock",
86+
"embeddings_model_id":"'$EMBEDDINGS_MODEL'",
87+
"model_id":"'$MODEL'"
88+
}' | jq
89+
}

scripts/assistant/start.sh

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/bash
2+
3+
# Copyright OpenSearch Contributors
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
set -e
7+
8+
. scripts/assistant/utils.sh
9+
. scripts/assistant/add_model.sh
10+
11+
function usage() {
12+
echo ""
13+
echo "This script is used to run OpenSearch Assistant"
14+
echo "--------------------------------------------------------------------------"
15+
echo "Usage: $0 [args]"
16+
echo ""
17+
echo "Optional arguments:"
18+
echo -e "-b BIND_ADDRESS\t, defaults to localhost | 127.0.0.1, can be changed to any IP or domain name for the cluster location."
19+
echo -e "-p BIND_PORT\t, defaults to 5601 depends on OpenSearch or Dashboards, can be changed to any port for the cluster location."
20+
echo -e "-c CREDENTIAL\t(password), defaults to admin"
21+
echo -e "-h\tPrint this message."
22+
echo "--------------------------------------------------------------------------"
23+
}
24+
25+
while getopts ":h:b:p:c:" arg; do
26+
case $arg in
27+
h)
28+
usage
29+
exit 1
30+
;;
31+
b)
32+
BIND_ADDRESS=$OPTARG
33+
;;
34+
p)
35+
BIND_PORT=$OPTARG
36+
;;
37+
c)
38+
CREDENTIAL=$OPTARG
39+
;;
40+
:)
41+
echo "-${OPTARG} requires an argument"
42+
usage
43+
exit 1
44+
;;
45+
?)
46+
echo "Invalid option: -${OPTARG}"
47+
exit 1
48+
;;
49+
esac
50+
done
51+
52+
[ -z "$BIND_ADDRESS" ] && BIND_ADDRESS="localhost"
53+
[ -z "$BIND_PORT" ] && BIND_PORT="9200"
54+
[ -z "$CREDENTIAL" ] && CREDENTIAL="admin"
55+
[ -z "$REGION" ] && REGION="us-west-2"
56+
57+
PARENT_PID_LIST=()
58+
59+
PACKAGE_VERSION=$(yarn --silent pkg-version)
60+
61+
# define assistant path
62+
CWD=$(pwd)
63+
SNAPSHOT_DIR="$CWD/.opensearch"
64+
LOGS_DIR="$SNAPSHOT_DIR/$PACKAGE_VERSION/logs"
65+
66+
# Main function
67+
function execute() {
68+
export initialAdminPassword=$CREDENTIAL
69+
CLUSTER_SETTINGS="snapshot --assistant --security"
70+
CLUSTER_SETTINGS+=" -E plugins.ml_commons.only_run_on_ml_node=true"
71+
72+
run_opensearch || clean
73+
check_opensearch_status
74+
echo "Attempting to add models..."
75+
echo "(Ensure your environment is exporting your credentials)"
76+
(add_model > $LOGS_DIR/add_model.log 2>&1 || clean) &
77+
78+
export OPENSEARCH_USERNAME=kibanaserver
79+
export OPENSEARCH_PASSWORD=kibanaserver
80+
$CWD/scripts/use_node $CWD/scripts/opensearch_dashboards --dev --security || clean
81+
}
82+
83+
execute
84+
clean
85+
exit 0

scripts/assistant/utils.sh

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/bin/bash
2+
3+
# Copyright OpenSearch Contributors
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
set -e
7+
8+
function open_artifact() {
9+
artifact_dir=$1
10+
artifact=$2
11+
cd $artifact_dir
12+
13+
# check if artifact provided is URL or attempt if passing by absolute path
14+
if curl -I -L $artifact; then
15+
curl -L $artifact | tar -xz --strip-components=1
16+
else
17+
echo "Artifact is not a URL; attempting to unarchive a local file..."
18+
tar -xf $artifact --strip-components=1
19+
fi
20+
}
21+
22+
# remove the running opensearch process
23+
function clean() {
24+
echo "Attempt to Terminate Process with PID: ${PARENT_PID_LIST[*]}"
25+
for pid_kill in "${PARENT_PID_LIST[@]}"
26+
do
27+
echo "Closing PID $pid_kill"
28+
kill $pid_kill || true
29+
done
30+
PARENT_PID_LIST=()
31+
}
32+
33+
function spawn_process_and_save_PID() {
34+
echo "Spawn '$@'"
35+
eval $@
36+
curr_pid=$!
37+
echo "PID: $curr_pid"
38+
PARENT_PID_LIST+=( $curr_pid )
39+
}
40+
41+
# Print out a textfile line by line
42+
function print_txt() {
43+
while IFS= read -r line; do
44+
echo "text read from $1: $line"
45+
done < $1
46+
}
47+
48+
# this function is used to check the running status of OpenSearch or OpenSearch Dashboards
49+
# $1 is the path to the tmp file which saves the running status
50+
# $2 is the error msg to check
51+
# $3 is the url to curl
52+
# $4 contains arguments that need to be passed to the curl command
53+
function check_status() {
54+
# Calculate end time as 350s from now
55+
check_status_end_time=$(expr 350 + "$(date '+%s')")
56+
57+
while [ ! -e $1 ] || ! grep -q "$2" $1; do
58+
sleep 1
59+
# Stop checking after $check_status_end_time
60+
if [ $check_status_end_time -lt $(date '+%s') ]; then
61+
echo "Error: Status check has timed out"
62+
exit 1
63+
fi
64+
done
65+
}
66+
67+
# Checks the running status of OpenSearch
68+
# it calls check_status and passes the OpenSearch tmp file path, error msg, url, and arguments
69+
# if success, the while loop in the check_status will end and it prints out "OpenSearch is up!"
70+
function check_opensearch_status() {
71+
echo "Checking the status OpenSearch..."
72+
# define other paths and tmp files
73+
OPENSEARCH_FILE='opensearch.log'
74+
OPENSEARCH_LOG_PATH="$LOGS_DIR/$OPENSEARCH_FILE"
75+
76+
OPENSEARCH_MSG="ML configuration initialized successfully"
77+
check_status $OPENSEARCH_LOG_PATH "$OPENSEARCH_MSG" 2>&1
78+
echo "OpenSearch is up!"
79+
}
80+
81+
# Starts OpenSearch
82+
function run_opensearch() {
83+
echo "[ Attempting to start OpenSearch... ]"
84+
rm -rf $LOGS_DIR/opensearch.log
85+
spawn_process_and_save_PID "$CWD/scripts/use_node $CWD/scripts/opensearch $CLUSTER_SETTINGS > $LOGS_DIR/opensearch.log 2>&1 &"
86+
}

scripts/pre_install.sh

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/bash
2+
3+
# Copyright OpenSearch Contributors
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
set -e
7+
8+
[ -z "$SUPPORTED_VERSION" ] && SUPPORTED_VERSION="2.11.0"
9+
10+
cp -r scripts/assistant ../../scripts
11+
sed -i -E "s|(\"version\": \")[^\"]*|\1${SUPPORTED_VERSION}|" ../../package.json

0 commit comments

Comments
 (0)