Gouzi Mohaled commited on
Commit
322135d
·
1 Parent(s): 55c9a77

Ajout du dossier tools

Browse files
tools/cargo_cmd_arch.sh ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ case $TARGETARCH in
2
+ "amd64")
3
+ echo "./mold/bin/mold -run cargo"
4
+ ;;
5
+ "arm64")
6
+ echo "cargo"
7
+ ;;
8
+ esac
tools/clean-old-rocksdb-logs.sh ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ # Clean old RocksDB log files, always leave the last two.
4
+ #
5
+ # On invocation, the script will prompt whether to run in dry mode.
6
+ #
7
+ # Script MUST be run in the ./storage directory of Qdrant.
8
+
9
+ # Number of newest old logs to keep
10
+ KEEP_N=2
11
+ DRY=1
12
+ CLEAN_COUNT=0
13
+
14
+ set -e
15
+
16
+ function main {
17
+ # Ensure script is run in storage directory
18
+ if [[ "$(basename "$(pwd)")" != "storage" ]]; then
19
+ echo Error: script must be run in ./storage directory
20
+ echo Currently in "$(pwd)"
21
+ exit 1
22
+ fi
23
+
24
+ echo This script removes old and obsolete log files to clean up disk space.
25
+ echo It is potentionally dangerous. Always make sure you have a backup before running this.
26
+ echo Qdrant must be stopped before running this script.
27
+
28
+ # Ask for dry run
29
+ yes_or_no "Dry run?" || DRY=0
30
+
31
+ # Confirmation
32
+ if [[ $DRY == 0 ]]; then
33
+ yes_or_no "Are you sure you want to continue?" || (echo "Aborted"; exit 1)
34
+ fi
35
+
36
+ # Go through collections/shards/segments to clean
37
+ for collection in $(find collections/* -maxdepth 0 -type d); do
38
+ echo "Cleaning collection: $collection"
39
+ for shard in $(find $collection/* -maxdepth 0 -type d); do
40
+ for segment in $(find $shard/segments/* -maxdepth 0 -type d); do
41
+ clean_segment "$segment"
42
+ done
43
+ done
44
+ done
45
+
46
+ echo Cleaned $CLEAN_COUNT old log files
47
+ }
48
+
49
+ function yes_or_no {
50
+ while true; do
51
+ read -p "$* [y/n]: " yn
52
+ case $yn in
53
+ [Yy]*) return 0 ;;
54
+ [Nn]*) return 1 ;;
55
+ esac
56
+ done
57
+ }
58
+
59
+ function clean_segment {
60
+ remove_oldest_logs_in "$segment"
61
+
62
+ if [[ -d "$segment/payload_index" ]]; then
63
+ remove_oldest_logs_in "$segment/payload_index"
64
+ fi
65
+ }
66
+
67
+ function remove_oldest_logs_in {
68
+ FILES=$(find "$1" -maxdepth 1 -name 'LOG.old.*' | sort -n | head -n -${KEEP_N})
69
+ CLEAN_COUNT=$((CLEAN_COUNT + $(echo "$FILES" | wc -w)))
70
+ remove $FILES
71
+ }
72
+
73
+ function remove {
74
+ if [[ -z "$*" ]]; then
75
+ return
76
+ fi
77
+
78
+ echo "+ rm -f" $*
79
+ if [[ $DRY == 0 ]]; then
80
+ rm -f $*
81
+ fi
82
+ }
83
+
84
+ main
tools/entrypoint.sh ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # Script to run qdrant in docker container and handle contingencies, like OOM.
3
+ # The functioning logic is as follows:
4
+ # - If recovery mode is allowed, we check if qdrant was killed during initialization or not.
5
+ # - If it was killed during initialization, we remove run qdrant in recovery mode
6
+ # - If it was killed after initialization, do nothing and restart container
7
+ # - If recovery mode is not allowed, we just restart container
8
+
9
+ _term () {
10
+ kill -TERM "$QDRANT_PID" 2>/dev/null
11
+ }
12
+
13
+ trap _term SIGTERM
14
+
15
+ _interrupt () {
16
+ kill -INT "$QDRANT_PID" 2>/dev/null
17
+ }
18
+
19
+ trap _interrupt SIGINT
20
+
21
+ ./qdrant $@ &
22
+
23
+ # Get PID for the traps
24
+ QDRANT_PID=$!
25
+ wait $QDRANT_PID
26
+
27
+ EXIT_CODE=$?
28
+
29
+ QDRANT_ALLOW_RECOVERY_MODE=${QDRANT_ALLOW_RECOVERY_MODE:-false}
30
+
31
+ # Check that recovery mode is allowed
32
+ if [ "$QDRANT_ALLOW_RECOVERY_MODE" != true ]; then
33
+ exit $EXIT_CODE
34
+ fi
35
+
36
+ # Check that qdrant was killed (exit code 137)
37
+ # Ideally, we want to catch only OOM, but it's not possible to distinguish it from random kill signal
38
+ if [ $EXIT_CODE != 137 ]; then
39
+ exit $EXIT_CODE
40
+ fi
41
+
42
+ QDRANT_INIT_FILE_PATH=${QDRANT_INIT_FILE_PATH:-'.qdrant-initialized'}
43
+ RECOVERY_MESSAGE="Qdrant was killed during initialization. Most likely it's Out-of-Memory.
44
+ Please check memory consumption, increase memory limit or remove some collections and restart"
45
+
46
+ # Check that qdrant was initialized
47
+ # Qdrant creates QDRANT_INIT_FILE_PATH file after initialization
48
+ # So if it doesn't exist, qdrant was killed during initialization
49
+ if [ ! -f "$QDRANT_INIT_FILE_PATH" ]; then
50
+ # Run qdrant in recovery mode.
51
+ # No collection operations are allowed in recovery mode except for removing collections
52
+ QDRANT__STORAGE__RECOVERY_MODE="$RECOVERY_MESSAGE" ./qdrant $@ &
53
+ # Get PID for the traps
54
+ QDRANT_PID=$!
55
+ wait $QDRANT_PID
56
+ exit $?
57
+ fi
58
+
59
+ exit $EXIT_CODE
tools/generate_docker_compose_cluster.sh ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ # Generate a docker-compose configuration for a cluster.
4
+ #
5
+ # Parameters:
6
+ # - $1: number of nodes (default: 5)
7
+ # - $2: base port (default: 6330)
8
+ #
9
+ # Example usage:
10
+ # ./generate_docker_compose_cluster.sh 5 > docker-compose.yaml
11
+
12
+ set -euo pipefail
13
+
14
+ declare NODES="${1:-5}"
15
+ declare BASE_PORT="${2:-6330}"
16
+
17
+ cat <<-EOF
18
+ version: "3.7"
19
+
20
+ services:
21
+ EOF
22
+
23
+ for ((node=0; node<NODES; node++))
24
+ do
25
+ declare SERVICE_NAME=qdrant_node_$node
26
+
27
+ declare HTTP_PORT=$((BASE_PORT + node * 10 + 3))
28
+ declare GRPC_PORT=$((BASE_PORT + node * 10 + 4))
29
+
30
+ if ((node == 0))
31
+ then
32
+ declare COMMAND="./qdrant --uri 'http://$SERVICE_NAME:6335'"
33
+ else
34
+ declare COMMAND="bash -c \"sleep $((10 + node / 10 + RANDOM % 10)) && ./qdrant --bootstrap 'http://qdrant_node_0:6335' --uri 'http://$SERVICE_NAME:6335'\""
35
+ fi
36
+
37
+ cat <<-EOF
38
+ $SERVICE_NAME:
39
+ image: qdrant/qdrant:latest
40
+ command: $COMMAND
41
+ restart: always
42
+ environment:
43
+ - QDRANT__SERVICE__GRPC_PORT=6334
44
+ - QDRANT__CLUSTER__ENABLED=true
45
+ - QDRANT__CLUSTER__P2P__PORT=6335
46
+ - QDRANT__CLUSTER__CONSENSUS__MAX_MESSAGE_QUEUE_SIZE=5000
47
+ - QDRANT__LOG_LEVEL=debug,raft=info
48
+ ports:
49
+ - "$HTTP_PORT:6333"
50
+ - "$GRPC_PORT:6334"
51
+ deploy:
52
+ resources:
53
+ limits:
54
+ cpus: "0.3"
55
+
56
+ EOF
57
+ done
tools/generate_grpc_docs.sh ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ # Ensure current path is project root
6
+ cd "$(dirname "$0")/../"
7
+
8
+ # Create a temporary directory and store its name in a variable.
9
+ TEMPD=$(mktemp -d -t qdrant_docs.XXXXXXXXXX)
10
+ trap 'rm -rf -- "$TEMPD"' EXIT
11
+
12
+ cp -r "$PWD"/lib/api/src/grpc/proto/* "$TEMPD"
13
+
14
+ # Do not generate docs for internal services
15
+ rm "$TEMPD/collections_internal_service.proto"
16
+ rm "$TEMPD/points_internal_service.proto"
17
+ rm "$TEMPD/shard_snapshots_service.proto"
18
+ rm "$TEMPD/raft_service.proto"
19
+
20
+ cat "$TEMPD/qdrant.proto" \
21
+ | grep -v 'collections_internal_service.proto' \
22
+ | grep -v 'points_internal_service.proto' \
23
+ | grep -v 'shard_snapshots_service.proto' \
24
+ | grep -v 'raft_service.proto'\
25
+ > "$TEMPD/qdrant.proto.tmp"
26
+ mv "$TEMPD/qdrant.proto.tmp" "$TEMPD/qdrant.proto"
27
+
28
+ docker run --rm \
29
+ -u "$(id -u):$(id -g)" \
30
+ -v "$PWD/docs/grpc":/out \
31
+ -v "$TEMPD":/protos \
32
+ pseudomuto/protoc-gen-doc --doc_opt=markdown,docs.md
tools/generate_openapi_models.sh ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # This script generate model definitions for OpenAPI 3.0 documentation
3
+
4
+ set -e
5
+
6
+ # Ensure current path is project root
7
+ cd "$(dirname "$0")/../"
8
+
9
+ # Fallback to dockerized utilities if they are not installed locally
10
+
11
+ if command -v ytt &>/dev/null; then
12
+ sh_with_ytt() { sh -c "$1"; }
13
+ else
14
+ sh_with_ytt() { docker run --rm -v "${PWD}":/workspace --entrypoint sh gerritk/ytt -c "$1"; }
15
+ fi
16
+
17
+ if ! yq --version 2>&1 | grep -q mikefarah; then
18
+ yq() { docker run --rm -v "${PWD}":/workdir mikefarah/yq "$@"; }
19
+ fi
20
+
21
+ # Apply `ytt` template engine to obtain OpenAPI definitions for REST endpoints
22
+
23
+ sh_with_ytt '
24
+ set -e
25
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-shards.ytt.yaml > ./openapi/openapi-shards.yaml
26
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-service.ytt.yaml > ./openapi/openapi-service.yaml
27
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-cluster.ytt.yaml > ./openapi/openapi-cluster.yaml
28
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-collections.ytt.yaml > ./openapi/openapi-collections.yaml
29
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-snapshots.ytt.yaml > ./openapi/openapi-snapshots.yaml
30
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-shard-snapshots.ytt.yaml > ./openapi/openapi-shard-snapshots.yaml
31
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-points.ytt.yaml > ./openapi/openapi-points.yaml
32
+ ytt -f ./openapi/openapi.lib.yml -f ./openapi/openapi-main.ytt.yaml > ./openapi/openapi-main.yaml
33
+ '
34
+
35
+ # Generates models from internal service structures
36
+ cargo run --package qdrant --bin schema_generator > ./openapi/schemas/AllDefinitions.json
37
+
38
+ docker build tools/schema2openapi --tag schema2openapi
39
+
40
+ docker run --rm \
41
+ -v "$PWD/openapi/schemas/AllDefinitions.json:/app/schema.json" \
42
+ schema2openapi | sed -e 's%#/definitions/%#/components/schemas/%g' >./openapi/models.json
43
+
44
+ yq eval -o yaml -P ./openapi/models.json > ./openapi/models.yaml
45
+
46
+ # Merge all *.yaml files together into a single-file OpenAPI definition
47
+ yq eval-all '. as $item ireduce ({}; . *+ $item)' \
48
+ ./openapi/openapi-shards.yaml \
49
+ ./openapi/openapi-service.yaml \
50
+ ./openapi/openapi-cluster.yaml \
51
+ ./openapi/openapi-collections.yaml \
52
+ ./openapi/openapi-snapshots.yaml \
53
+ ./openapi/openapi-shard-snapshots.yaml \
54
+ ./openapi/openapi-points.yaml \
55
+ ./openapi/openapi-main.yaml \
56
+ ./openapi/models.yaml > ./openapi/openapi-merged.yaml
57
+
58
+ docker run --rm -v "${PWD}"/openapi:/spec redocly/openapi-cli:v1.0.0-beta.88 lint openapi-merged.yaml
59
+
60
+ yq eval -o=json ./openapi/openapi-merged.yaml | jq > ./openapi/openapi-merged.json
61
+
62
+ cp ./openapi/openapi-merged.json ./docs/redoc/master/openapi.json
tools/missed_cherry_picks.sh ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ # List all commits that have not been cherry-picked from dev into master yet
4
+ #
5
+ # Example usage:
6
+ # ./missed_cherry_picks.sh
7
+
8
+ set -euo pipefail
9
+
10
+ # Ignore all commits upto and including this commit hash on dev
11
+ IGNORE_UPTO=9d83ef2a6d24cfc5b8c5a504d71710fecabfc7fe
12
+
13
+ # Fetch latest branch info from remote
14
+ git fetch -q origin master
15
+ git fetch -q origin dev
16
+
17
+ # Get remote/local commit hash of dev, user must have up-to-date branch
18
+ REMOTE_SHA=$(git log -n 1 --pretty=format:"%H" origin/dev)
19
+ LOCAL_SHA=$(git log -n 1 --pretty=format:"%H" dev)
20
+ if [[ "$REMOTE_SHA" != "$LOCAL_SHA" ]]; then
21
+ echo Error: your local dev branch must match the current remote
22
+ echo To pull latest dev, use: git checkout dev \&\& git pull --ff-only origin dev
23
+ exit 1
24
+ fi
25
+
26
+ # List all commits yet-to-be-cherry-picked
27
+ git cherry -v origin/master origin/dev $IGNORE_UPTO \
28
+ | grep --color=never '^+ ' \
29
+ | cut -d' ' -f2-
tools/nix/npins/default.nix ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated by npins. Do not modify; will be overwritten regularly
2
+ let
3
+ data = builtins.fromJSON (builtins.readFile ./sources.json);
4
+ version = data.version;
5
+
6
+ mkSource =
7
+ spec:
8
+ assert spec ? type;
9
+ let
10
+ path =
11
+ if spec.type == "Git" then
12
+ mkGitSource spec
13
+ else if spec.type == "GitRelease" then
14
+ mkGitSource spec
15
+ else if spec.type == "PyPi" then
16
+ mkPyPiSource spec
17
+ else if spec.type == "Channel" then
18
+ mkChannelSource spec
19
+ else
20
+ builtins.throw "Unknown source type ${spec.type}";
21
+ in
22
+ spec // { outPath = path; };
23
+
24
+ mkGitSource =
25
+ {
26
+ repository,
27
+ revision,
28
+ url ? null,
29
+ hash,
30
+ branch ? null,
31
+ ...
32
+ }:
33
+ assert repository ? type;
34
+ # At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
35
+ # In the latter case, there we will always be an url to the tarball
36
+ if url != null then
37
+ (builtins.fetchTarball {
38
+ inherit url;
39
+ sha256 = hash; # FIXME: check nix version & use SRI hashes
40
+ })
41
+ else
42
+ assert repository.type == "Git";
43
+ let
44
+ urlToName =
45
+ url: rev:
46
+ let
47
+ matched = builtins.match "^.*/([^/]*)(\\.git)?$" repository.url;
48
+
49
+ short = builtins.substring 0 7 rev;
50
+
51
+ appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else "";
52
+ in
53
+ "${if matched == null then "source" else builtins.head matched}${appendShort}";
54
+ name = urlToName repository.url revision;
55
+ in
56
+ builtins.fetchGit {
57
+ url = repository.url;
58
+ rev = revision;
59
+ inherit name;
60
+ # hash = hash;
61
+ };
62
+
63
+ mkPyPiSource =
64
+ { url, hash, ... }:
65
+ builtins.fetchurl {
66
+ inherit url;
67
+ sha256 = hash;
68
+ };
69
+
70
+ mkChannelSource =
71
+ { url, hash, ... }:
72
+ builtins.fetchTarball {
73
+ inherit url;
74
+ sha256 = hash;
75
+ };
76
+ in
77
+ if version == 3 then
78
+ builtins.mapAttrs (_: mkSource) data.pins
79
+ else
80
+ throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
tools/nix/npins/sources.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "pins": {
3
+ "fenix": {
4
+ "type": "Git",
5
+ "repository": {
6
+ "type": "GitHub",
7
+ "owner": "nix-community",
8
+ "repo": "fenix"
9
+ },
10
+ "branch": "main",
11
+ "revision": "cdfd7bf3e3edaf9e3f6d1e397d3ee601e513613c",
12
+ "url": "https://github.com/nix-community/fenix/archive/cdfd7bf3e3edaf9e3f6d1e397d3ee601e513613c.tar.gz",
13
+ "hash": "1h9p1s3bkrilyafx15qzb5y5m6wdip9iiykv5mgbl48vhvgip2c3"
14
+ },
15
+ "nixpkgs": {
16
+ "type": "Channel",
17
+ "name": "nixpkgs-unstable",
18
+ "url": "https://releases.nixos.org/nixpkgs/nixpkgs-24.11pre688989.e2f08f4d8b3e/nixexprs.tar.xz",
19
+ "hash": "14hxnbnm41j3px7819dqzmfnqpalgxcnxy7gk8qi0lyyjgzjf103"
20
+ },
21
+ "poetry2nix": {
22
+ "type": "Git",
23
+ "repository": {
24
+ "type": "GitHub",
25
+ "owner": "nix-community",
26
+ "repo": "poetry2nix"
27
+ },
28
+ "branch": "master",
29
+ "revision": "ef877b8e159b23f36ebc39155021657bed744a68",
30
+ "url": "https://github.com/nix-community/poetry2nix/archive/ef877b8e159b23f36ebc39155021657bed744a68.tar.gz",
31
+ "hash": "1kgfnxrji87fdh0vjldkskcs2cnizghsbczdakhxak1y1kk0njff"
32
+ }
33
+ },
34
+ "version": 3
35
+ }
tools/nix/update.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ import argparse
4
+ import hashlib
5
+ import json
6
+ import pathlib
7
+ import re
8
+ import shlex
9
+ import shutil
10
+ import subprocess
11
+ import sys
12
+ import tomllib
13
+ import urllib.request
14
+
15
+
16
+ def main() -> None:
17
+ parser = argparse.ArgumentParser(
18
+ description="Update the versions.json and nix dependencies",
19
+ )
20
+ parser.add_argument(
21
+ "--nix",
22
+ action=argparse.BooleanOptionalAction,
23
+ default=True,
24
+ help="update nix dependencies by running `npins update` (default: yes)",
25
+ )
26
+ parser.add_argument(
27
+ "--nightly",
28
+ type=str,
29
+ help="nightly version, e.g. 2021-01-01 (default: use latest)",
30
+ )
31
+ parser.add_argument(
32
+ "--stable",
33
+ type=str,
34
+ help="stable version, e.g. 1.76.0 (default: use latest)",
35
+ )
36
+ args = parser.parse_args()
37
+
38
+ if args.nix:
39
+ if shutil.which("npins") is not None:
40
+ command = ["npins", "update"]
41
+ else:
42
+ command = ["nix-shell", "-p", "npins", "--run", "npins update"]
43
+ print(f"Running {shlex.join(command)}", file=sys.stderr)
44
+ subprocess.run(
45
+ args=command,
46
+ cwd=pathlib.Path(__file__).parent,
47
+ check=True,
48
+ )
49
+
50
+ print("Updating versions.json", file=sys.stderr)
51
+ d = f"{args.nightly}/" if args.nightly else ""
52
+ url = f"https://static.rust-lang.org/dist/{d}channel-rust-nightly.toml"
53
+ with urllib.request.urlopen(url) as response:
54
+ data = response.read()
55
+ nightly_sha256 = hashlib.sha256(data).digest().hex()
56
+ nightly_date = tomllib.loads(data.decode("utf-8"))["date"]
57
+
58
+ d = args.stable if args.stable else "stable"
59
+ url = f"https://static.rust-lang.org/dist/channel-rust-{d}.toml"
60
+ with urllib.request.urlopen(url) as response:
61
+ data = response.read()
62
+ stable_sha256 = hashlib.sha256(data).digest().hex()
63
+ stable_version = tomllib.loads(data.decode("utf-8"))["pkg"]["rust"]["version"]
64
+ m = re.match(r"^(\d+\.\d+\.\d+) \(.*\)$", stable_version)
65
+ if not m:
66
+ raise ValueError(f"Failed to parse stable version: {stable_version}")
67
+ stable_version = m[1]
68
+
69
+ result = {
70
+ "#": "This file is autogenerated by ./update.py",
71
+ "nightly": {
72
+ "date": nightly_date,
73
+ "sha256": nightly_sha256,
74
+ },
75
+ "stable": {
76
+ "version": stable_version,
77
+ "sha256": stable_sha256,
78
+ },
79
+ }
80
+
81
+ with open(pathlib.Path(__file__).parent / "versions.json", "w") as f:
82
+ f.write(json.dumps(result, indent=2) + "\n")
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()
tools/nix/versions.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "#": "This file is autogenerated by ./update.py",
3
+ "nightly": {
4
+ "date": "2024-10-05",
5
+ "sha256": "6602972eedaba88e29e24197e471b6fac66e605868d6f2e387a68b636d5ea0f2"
6
+ },
7
+ "stable": {
8
+ "version": "1.81.0",
9
+ "sha256": "5596679723faf7e63772bacb1d0c898abaa51eb4ed193b328929d907c8c4bd5a"
10
+ }
11
+ }
tools/schema2openapi/Dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:lts-alpine
2
+
3
+ WORKDIR /app
4
+
5
+ COPY . .
6
+
7
+ RUN npm install
8
+
9
+ CMD ["node", "convert.js"]
tools/schema2openapi/convert.js ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const toOpenApi = require('@openapi-contrib/json-schema-to-openapi-schema');
2
+
3
+ const fs = require('fs');
4
+
5
+ let rawdata = fs.readFileSync('schema.json');
6
+
7
+ let schema = JSON.parse(rawdata);
8
+
9
+ // Generated result contains usage of "allOf" directive with a single class.
10
+ // It breaks client generator serves no function.
11
+ // This function should replace "allOf" directives with simple class usages
12
+ function replaceAllOf(schema) {
13
+ if (Array.isArray(schema)) {
14
+ var newSchema = [];
15
+ for (var k in schema) {
16
+ newSchema[k] = replaceAllOf(schema[k]);
17
+ }
18
+ return newSchema;
19
+ }
20
+ if (typeof schema === 'object' && schema !== null) {
21
+ var newSchema = {};
22
+ for (var k in schema) {
23
+ if (k === 'allOf' && schema[k].length === 1) {
24
+ newSchema = {...schema[k][0]};
25
+ break
26
+ } else {
27
+ newSchema[k] = replaceAllOf(schema[k]);
28
+ }
29
+ }
30
+ return newSchema;
31
+ }
32
+ return schema;
33
+ }
34
+
35
+
36
+
37
+ (async () => {
38
+ var convertedSchema = await toOpenApi(schema);
39
+
40
+ convertedSchema = replaceAllOf(convertedSchema);
41
+
42
+ for (var modelName in convertedSchema['definitions']) {
43
+ convertedSchema['definitions'][modelName]["$schema"] = schema["$schema"];
44
+ convertedSchema['definitions'][modelName] = await toOpenApi(convertedSchema['definitions'][modelName]);
45
+ }
46
+
47
+ console.log(JSON.stringify({components: {schemas: convertedSchema['definitions']}}, null, 4));
48
+ })();
49
+
50
+
51
+
52
+
tools/schema2openapi/package-lock.json ADDED
@@ -0,0 +1,443 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "tools",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 2,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "tools",
9
+ "version": "1.0.0",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "@openapi-contrib/json-schema-to-openapi-schema": "^1.3.0"
13
+ },
14
+ "devDependencies": {}
15
+ },
16
+ "node_modules/@cloudflare/json-schema-walker": {
17
+ "version": "0.1.1",
18
+ "resolved": "https://registry.npmjs.org/@cloudflare/json-schema-walker/-/json-schema-walker-0.1.1.tgz",
19
+ "integrity": "sha512-P3n0hEgk1m6uKWgL4Yb1owzXVG4pM70G4kRnDQxZXiVvfCRtaqiHu+ZRiRPzmwGBiLTO1LWc2yR1M8oz0YkXww=="
20
+ },
21
+ "node_modules/@openapi-contrib/json-schema-to-openapi-schema": {
22
+ "version": "1.3.0",
23
+ "resolved": "https://registry.npmjs.org/@openapi-contrib/json-schema-to-openapi-schema/-/json-schema-to-openapi-schema-1.3.0.tgz",
24
+ "integrity": "sha512-EaZoAT3U1oZObNQEiI1FDV1Lf/PHTkNCKtTVCOqdLY568iJfFV8nPvsKyKpUrmdCVJXtbNKeIrRFO2lJpa+EoA==",
25
+ "dependencies": {
26
+ "@cloudflare/json-schema-walker": "^0.1.1",
27
+ "@stoplight/json-ref-resolver": "^3.1.1",
28
+ "@stoplight/yaml": "^3.7.1",
29
+ "node-fetch": "^2.6.0",
30
+ "tslib": "^1.11.1"
31
+ },
32
+ "engines": {
33
+ "node": ">=10"
34
+ }
35
+ },
36
+ "node_modules/@stoplight/json": {
37
+ "version": "3.18.1",
38
+ "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.18.1.tgz",
39
+ "integrity": "sha512-QmELAqBS8DC+8YuG7+OvDVP6RaUVi8bzN0KKW2UEcZg+0a1sqeeZgfW079AmJIZg8HEN7udAt4iozIB8Dm0t1Q==",
40
+ "dependencies": {
41
+ "@stoplight/ordered-object-literal": "^1.0.2",
42
+ "@stoplight/types": "^13.0.0",
43
+ "jsonc-parser": "~2.2.1",
44
+ "lodash": "^4.17.21",
45
+ "safe-stable-stringify": "^1.1"
46
+ },
47
+ "engines": {
48
+ "node": ">=8.3.0"
49
+ }
50
+ },
51
+ "node_modules/@stoplight/json-ref-resolver": {
52
+ "version": "3.1.4",
53
+ "resolved": "https://registry.npmjs.org/@stoplight/json-ref-resolver/-/json-ref-resolver-3.1.4.tgz",
54
+ "integrity": "sha512-842JVmMsi++qpDuIX+JpQvK7YY8FXEZZb+/z4xuRfStOAVEryJT/tbgGOWxniSdxEl9Eni5D/I2afMyy6BuiNw==",
55
+ "dependencies": {
56
+ "@stoplight/json": "^3.17.0",
57
+ "@stoplight/path": "^1.3.2",
58
+ "@stoplight/types": "^12.3.0 || ^13.0.0",
59
+ "@types/urijs": "^1.19.19",
60
+ "dependency-graph": "~0.11.0",
61
+ "fast-memoize": "^2.5.2",
62
+ "immer": "^9.0.6",
63
+ "lodash": "^4.17.21",
64
+ "tslib": "^2.3.1",
65
+ "urijs": "^1.19.11"
66
+ },
67
+ "engines": {
68
+ "node": ">=8.3.0"
69
+ }
70
+ },
71
+ "node_modules/@stoplight/json-ref-resolver/node_modules/@stoplight/types": {
72
+ "version": "13.2.0",
73
+ "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.2.0.tgz",
74
+ "integrity": "sha512-V3BRfzWEAcCpICGQh/WW2LX4rcB2KagQ7/msf0BDTCF5qpFMSwOxcjv25k1NUMVQSh3qwGfGoka/gYGA5m+NQA==",
75
+ "dependencies": {
76
+ "@types/json-schema": "^7.0.4",
77
+ "utility-types": "^3.10.0"
78
+ },
79
+ "engines": {
80
+ "node": "^12.20 || >=14.13"
81
+ }
82
+ },
83
+ "node_modules/@stoplight/json-ref-resolver/node_modules/tslib": {
84
+ "version": "2.4.0",
85
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
86
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
87
+ },
88
+ "node_modules/@stoplight/json/node_modules/@stoplight/types": {
89
+ "version": "13.2.0",
90
+ "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.2.0.tgz",
91
+ "integrity": "sha512-V3BRfzWEAcCpICGQh/WW2LX4rcB2KagQ7/msf0BDTCF5qpFMSwOxcjv25k1NUMVQSh3qwGfGoka/gYGA5m+NQA==",
92
+ "dependencies": {
93
+ "@types/json-schema": "^7.0.4",
94
+ "utility-types": "^3.10.0"
95
+ },
96
+ "engines": {
97
+ "node": "^12.20 || >=14.13"
98
+ }
99
+ },
100
+ "node_modules/@stoplight/ordered-object-literal": {
101
+ "version": "1.0.3",
102
+ "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.3.tgz",
103
+ "integrity": "sha512-cjJ7PPkhgTXNMTkevAlmyrx9xOOCaI3c6rEeYb6VitL1o1WcZtrz9KyFyISmTmUa7yYTiy2IS/ud9S8s2sn3+A==",
104
+ "engines": {
105
+ "node": ">=8"
106
+ }
107
+ },
108
+ "node_modules/@stoplight/path": {
109
+ "version": "1.3.2",
110
+ "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz",
111
+ "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==",
112
+ "engines": {
113
+ "node": ">=8"
114
+ }
115
+ },
116
+ "node_modules/@stoplight/types": {
117
+ "version": "11.9.0",
118
+ "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-11.9.0.tgz",
119
+ "integrity": "sha512-4bzPpWZobt0e+d0OtALCJyl1HGzKo6ur21qxnId9dTl8v3yeD+5HJKZ2h1mv7e94debH5QDtimMU80V6jbXM8Q==",
120
+ "dependencies": {
121
+ "@types/json-schema": "^7.0.4",
122
+ "utility-types": "^3.10.0"
123
+ },
124
+ "engines": {
125
+ "node": ">=8"
126
+ }
127
+ },
128
+ "node_modules/@stoplight/yaml": {
129
+ "version": "3.8.1",
130
+ "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-3.8.1.tgz",
131
+ "integrity": "sha512-wbhcgo7dTjwjjwFziC/SAcQlwPucYhYq6vjzyOjj8zeOVnnmoa7hzU1i9Kj31473FG/re7xtt6j3LWu2VnYbxg==",
132
+ "dependencies": {
133
+ "@stoplight/ordered-object-literal": "^1.0.1",
134
+ "@stoplight/types": "^11.1.1",
135
+ "@stoplight/yaml-ast-parser": "0.0.45",
136
+ "lodash": "^4.17.15"
137
+ },
138
+ "engines": {
139
+ "node": ">=8.3.0"
140
+ }
141
+ },
142
+ "node_modules/@stoplight/yaml-ast-parser": {
143
+ "version": "0.0.45",
144
+ "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.45.tgz",
145
+ "integrity": "sha512-0MTEvgp3XMdeMUSTCGiNECuC+YlLbzytDEIOJVDHrrmzVZpIR3gGnHI6mmPI4P7saPxUiHxFF2uuoTuCNlKjrw=="
146
+ },
147
+ "node_modules/@types/json-schema": {
148
+ "version": "7.0.6",
149
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
150
+ "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw=="
151
+ },
152
+ "node_modules/@types/urijs": {
153
+ "version": "1.19.19",
154
+ "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz",
155
+ "integrity": "sha512-FDJNkyhmKLw7uEvTxx5tSXfPeQpO0iy73Ry+PmYZJvQy0QIWX8a7kJ4kLWRf+EbTPJEPDSgPXHaM7pzr5lmvCg=="
156
+ },
157
+ "node_modules/dependency-graph": {
158
+ "version": "0.11.0",
159
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
160
+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
161
+ "engines": {
162
+ "node": ">= 0.6.0"
163
+ }
164
+ },
165
+ "node_modules/fast-memoize": {
166
+ "version": "2.5.2",
167
+ "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
168
+ "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
169
+ },
170
+ "node_modules/immer": {
171
+ "version": "9.0.14",
172
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz",
173
+ "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw==",
174
+ "funding": {
175
+ "type": "opencollective",
176
+ "url": "https://opencollective.com/immer"
177
+ }
178
+ },
179
+ "node_modules/jsonc-parser": {
180
+ "version": "2.2.1",
181
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz",
182
+ "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="
183
+ },
184
+ "node_modules/lodash": {
185
+ "version": "4.17.21",
186
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
187
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
188
+ },
189
+ "node_modules/node-fetch": {
190
+ "version": "2.6.7",
191
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
192
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
193
+ "dependencies": {
194
+ "whatwg-url": "^5.0.0"
195
+ },
196
+ "engines": {
197
+ "node": "4.x || >=6.0.0"
198
+ },
199
+ "peerDependencies": {
200
+ "encoding": "^0.1.0"
201
+ },
202
+ "peerDependenciesMeta": {
203
+ "encoding": {
204
+ "optional": true
205
+ }
206
+ }
207
+ },
208
+ "node_modules/safe-stable-stringify": {
209
+ "version": "1.1.1",
210
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz",
211
+ "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="
212
+ },
213
+ "node_modules/tr46": {
214
+ "version": "0.0.3",
215
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
216
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
217
+ },
218
+ "node_modules/tslib": {
219
+ "version": "1.14.1",
220
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
221
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
222
+ },
223
+ "node_modules/urijs": {
224
+ "version": "1.19.11",
225
+ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz",
226
+ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="
227
+ },
228
+ "node_modules/utility-types": {
229
+ "version": "3.10.0",
230
+ "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
231
+ "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==",
232
+ "engines": {
233
+ "node": ">= 4"
234
+ }
235
+ },
236
+ "node_modules/webidl-conversions": {
237
+ "version": "3.0.1",
238
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
239
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
240
+ },
241
+ "node_modules/whatwg-url": {
242
+ "version": "5.0.0",
243
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
244
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
245
+ "dependencies": {
246
+ "tr46": "~0.0.3",
247
+ "webidl-conversions": "^3.0.0"
248
+ }
249
+ }
250
+ },
251
+ "dependencies": {
252
+ "@cloudflare/json-schema-walker": {
253
+ "version": "0.1.1",
254
+ "resolved": "https://registry.npmjs.org/@cloudflare/json-schema-walker/-/json-schema-walker-0.1.1.tgz",
255
+ "integrity": "sha512-P3n0hEgk1m6uKWgL4Yb1owzXVG4pM70G4kRnDQxZXiVvfCRtaqiHu+ZRiRPzmwGBiLTO1LWc2yR1M8oz0YkXww=="
256
+ },
257
+ "@openapi-contrib/json-schema-to-openapi-schema": {
258
+ "version": "1.3.0",
259
+ "resolved": "https://registry.npmjs.org/@openapi-contrib/json-schema-to-openapi-schema/-/json-schema-to-openapi-schema-1.3.0.tgz",
260
+ "integrity": "sha512-EaZoAT3U1oZObNQEiI1FDV1Lf/PHTkNCKtTVCOqdLY568iJfFV8nPvsKyKpUrmdCVJXtbNKeIrRFO2lJpa+EoA==",
261
+ "requires": {
262
+ "@cloudflare/json-schema-walker": "^0.1.1",
263
+ "@stoplight/json-ref-resolver": "^3.1.1",
264
+ "@stoplight/yaml": "^3.7.1",
265
+ "node-fetch": "^2.6.0",
266
+ "tslib": "^1.11.1"
267
+ }
268
+ },
269
+ "@stoplight/json": {
270
+ "version": "3.18.1",
271
+ "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.18.1.tgz",
272
+ "integrity": "sha512-QmELAqBS8DC+8YuG7+OvDVP6RaUVi8bzN0KKW2UEcZg+0a1sqeeZgfW079AmJIZg8HEN7udAt4iozIB8Dm0t1Q==",
273
+ "requires": {
274
+ "@stoplight/ordered-object-literal": "^1.0.2",
275
+ "@stoplight/types": "^13.0.0",
276
+ "jsonc-parser": "~2.2.1",
277
+ "lodash": "^4.17.21",
278
+ "safe-stable-stringify": "^1.1"
279
+ },
280
+ "dependencies": {
281
+ "@stoplight/types": {
282
+ "version": "13.2.0",
283
+ "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.2.0.tgz",
284
+ "integrity": "sha512-V3BRfzWEAcCpICGQh/WW2LX4rcB2KagQ7/msf0BDTCF5qpFMSwOxcjv25k1NUMVQSh3qwGfGoka/gYGA5m+NQA==",
285
+ "requires": {
286
+ "@types/json-schema": "^7.0.4",
287
+ "utility-types": "^3.10.0"
288
+ }
289
+ }
290
+ }
291
+ },
292
+ "@stoplight/json-ref-resolver": {
293
+ "version": "3.1.4",
294
+ "resolved": "https://registry.npmjs.org/@stoplight/json-ref-resolver/-/json-ref-resolver-3.1.4.tgz",
295
+ "integrity": "sha512-842JVmMsi++qpDuIX+JpQvK7YY8FXEZZb+/z4xuRfStOAVEryJT/tbgGOWxniSdxEl9Eni5D/I2afMyy6BuiNw==",
296
+ "requires": {
297
+ "@stoplight/json": "^3.17.0",
298
+ "@stoplight/path": "^1.3.2",
299
+ "@stoplight/types": "^12.3.0 || ^13.0.0",
300
+ "@types/urijs": "^1.19.19",
301
+ "dependency-graph": "~0.11.0",
302
+ "fast-memoize": "^2.5.2",
303
+ "immer": "^9.0.6",
304
+ "lodash": "^4.17.21",
305
+ "tslib": "^2.3.1",
306
+ "urijs": "^1.19.11"
307
+ },
308
+ "dependencies": {
309
+ "@stoplight/types": {
310
+ "version": "13.2.0",
311
+ "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.2.0.tgz",
312
+ "integrity": "sha512-V3BRfzWEAcCpICGQh/WW2LX4rcB2KagQ7/msf0BDTCF5qpFMSwOxcjv25k1NUMVQSh3qwGfGoka/gYGA5m+NQA==",
313
+ "requires": {
314
+ "@types/json-schema": "^7.0.4",
315
+ "utility-types": "^3.10.0"
316
+ }
317
+ },
318
+ "tslib": {
319
+ "version": "2.4.0",
320
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
321
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
322
+ }
323
+ }
324
+ },
325
+ "@stoplight/ordered-object-literal": {
326
+ "version": "1.0.3",
327
+ "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.3.tgz",
328
+ "integrity": "sha512-cjJ7PPkhgTXNMTkevAlmyrx9xOOCaI3c6rEeYb6VitL1o1WcZtrz9KyFyISmTmUa7yYTiy2IS/ud9S8s2sn3+A=="
329
+ },
330
+ "@stoplight/path": {
331
+ "version": "1.3.2",
332
+ "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz",
333
+ "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ=="
334
+ },
335
+ "@stoplight/types": {
336
+ "version": "11.9.0",
337
+ "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-11.9.0.tgz",
338
+ "integrity": "sha512-4bzPpWZobt0e+d0OtALCJyl1HGzKo6ur21qxnId9dTl8v3yeD+5HJKZ2h1mv7e94debH5QDtimMU80V6jbXM8Q==",
339
+ "requires": {
340
+ "@types/json-schema": "^7.0.4",
341
+ "utility-types": "^3.10.0"
342
+ }
343
+ },
344
+ "@stoplight/yaml": {
345
+ "version": "3.8.1",
346
+ "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-3.8.1.tgz",
347
+ "integrity": "sha512-wbhcgo7dTjwjjwFziC/SAcQlwPucYhYq6vjzyOjj8zeOVnnmoa7hzU1i9Kj31473FG/re7xtt6j3LWu2VnYbxg==",
348
+ "requires": {
349
+ "@stoplight/ordered-object-literal": "^1.0.1",
350
+ "@stoplight/types": "^11.1.1",
351
+ "@stoplight/yaml-ast-parser": "0.0.45",
352
+ "lodash": "^4.17.15"
353
+ }
354
+ },
355
+ "@stoplight/yaml-ast-parser": {
356
+ "version": "0.0.45",
357
+ "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.45.tgz",
358
+ "integrity": "sha512-0MTEvgp3XMdeMUSTCGiNECuC+YlLbzytDEIOJVDHrrmzVZpIR3gGnHI6mmPI4P7saPxUiHxFF2uuoTuCNlKjrw=="
359
+ },
360
+ "@types/json-schema": {
361
+ "version": "7.0.6",
362
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
363
+ "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw=="
364
+ },
365
+ "@types/urijs": {
366
+ "version": "1.19.19",
367
+ "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz",
368
+ "integrity": "sha512-FDJNkyhmKLw7uEvTxx5tSXfPeQpO0iy73Ry+PmYZJvQy0QIWX8a7kJ4kLWRf+EbTPJEPDSgPXHaM7pzr5lmvCg=="
369
+ },
370
+ "dependency-graph": {
371
+ "version": "0.11.0",
372
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
373
+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg=="
374
+ },
375
+ "fast-memoize": {
376
+ "version": "2.5.2",
377
+ "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
378
+ "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
379
+ },
380
+ "immer": {
381
+ "version": "9.0.14",
382
+ "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz",
383
+ "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw=="
384
+ },
385
+ "jsonc-parser": {
386
+ "version": "2.2.1",
387
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz",
388
+ "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="
389
+ },
390
+ "lodash": {
391
+ "version": "4.17.21",
392
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
393
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
394
+ },
395
+ "node-fetch": {
396
+ "version": "2.6.7",
397
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
398
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
399
+ "requires": {
400
+ "whatwg-url": "^5.0.0"
401
+ }
402
+ },
403
+ "safe-stable-stringify": {
404
+ "version": "1.1.1",
405
+ "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz",
406
+ "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="
407
+ },
408
+ "tr46": {
409
+ "version": "0.0.3",
410
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
411
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
412
+ },
413
+ "tslib": {
414
+ "version": "1.14.1",
415
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
416
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
417
+ },
418
+ "urijs": {
419
+ "version": "1.19.11",
420
+ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz",
421
+ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="
422
+ },
423
+ "utility-types": {
424
+ "version": "3.10.0",
425
+ "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
426
+ "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg=="
427
+ },
428
+ "webidl-conversions": {
429
+ "version": "3.0.1",
430
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
431
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
432
+ },
433
+ "whatwg-url": {
434
+ "version": "5.0.0",
435
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
436
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
437
+ "requires": {
438
+ "tr46": "~0.0.3",
439
+ "webidl-conversions": "^3.0.0"
440
+ }
441
+ }
442
+ }
443
+ }
tools/schema2openapi/package.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "tools",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "convert.js",
6
+ "dependencies": {
7
+ "@openapi-contrib/json-schema-to-openapi-schema": "^1.3.0"
8
+ },
9
+ "devDependencies": {},
10
+ "scripts": {
11
+ "convert": "node convert.js"
12
+ },
13
+ "author": "",
14
+ "license": "ISC"
15
+ }
tools/schema2openapi/schema.json ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "StorageOps",
4
+ "anyOf": [
5
+ {
6
+ "description": "Create new collection and (optionally) specify index params",
7
+ "type": "object",
8
+ "required": [
9
+ "create_collection"
10
+ ],
11
+ "properties": {
12
+ "create_collection": {
13
+ "type": "object",
14
+ "required": [
15
+ "distance",
16
+ "name",
17
+ "vector_size"
18
+ ],
19
+ "properties": {
20
+ "distance": {
21
+ "$ref": "#/definitions/Distance"
22
+ },
23
+ "index": {
24
+ "anyOf": [
25
+ {
26
+ "$ref": "#/definitions/Indexes"
27
+ },
28
+ {
29
+ "type": "null"
30
+ }
31
+ ]
32
+ },
33
+ "name": {
34
+ "type": "string"
35
+ },
36
+ "vector_size": {
37
+ "type": "integer",
38
+ "format": "uint",
39
+ "minimum": 0.0
40
+ }
41
+ }
42
+ }
43
+ }
44
+ },
45
+ {
46
+ "description": "Delete collection with given name",
47
+ "type": "object",
48
+ "required": [
49
+ "delete_collection"
50
+ ],
51
+ "properties": {
52
+ "delete_collection": {
53
+ "type": "string"
54
+ }
55
+ }
56
+ },
57
+ {
58
+ "description": "Perform changes of collection aliases",
59
+ "type": "object",
60
+ "required": [
61
+ "change_aliases"
62
+ ],
63
+ "properties": {
64
+ "change_aliases": {
65
+ "type": "object",
66
+ "required": [
67
+ "actions"
68
+ ],
69
+ "properties": {
70
+ "actions": {
71
+ "type": "array",
72
+ "items": {
73
+ "$ref": "#/definitions/AliasOperations"
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ ],
81
+ "definitions": {
82
+ "AliasOperations": {
83
+ "anyOf": [
84
+ {
85
+ "type": "object",
86
+ "required": [
87
+ "create_alias"
88
+ ],
89
+ "properties": {
90
+ "create_alias": {
91
+ "type": "object",
92
+ "required": [
93
+ "alias_name",
94
+ "collection_name"
95
+ ],
96
+ "properties": {
97
+ "alias_name": {
98
+ "type": "string"
99
+ },
100
+ "collection_name": {
101
+ "type": "string"
102
+ }
103
+ }
104
+ }
105
+ }
106
+ },
107
+ {
108
+ "type": "object",
109
+ "required": [
110
+ "delete_alias"
111
+ ],
112
+ "properties": {
113
+ "delete_alias": {
114
+ "type": "object",
115
+ "required": [
116
+ "alias_name"
117
+ ],
118
+ "properties": {
119
+ "alias_name": {
120
+ "type": "string"
121
+ }
122
+ }
123
+ }
124
+ }
125
+ },
126
+ {
127
+ "type": "object",
128
+ "required": [
129
+ "rename_alias"
130
+ ],
131
+ "properties": {
132
+ "rename_alias": {
133
+ "type": "object",
134
+ "required": [
135
+ "new_alias_name",
136
+ "old_alias_name"
137
+ ],
138
+ "properties": {
139
+ "new_alias_name": {
140
+ "type": "string"
141
+ },
142
+ "old_alias_name": {
143
+ "type": "string"
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ ]
150
+ },
151
+ "Distance": {
152
+ "description": "Type of internal tags, build from payload",
153
+ "type": "string",
154
+ "enum": [
155
+ "Cosine",
156
+ "Euclid",
157
+ "Dot",
158
+ "Manhattan"
159
+ ]
160
+ },
161
+ "Indexes": {
162
+ "anyOf": [
163
+ {
164
+ "type": "object",
165
+ "required": [
166
+ "options",
167
+ "type"
168
+ ],
169
+ "properties": {
170
+ "options": {
171
+ "type": "object"
172
+ },
173
+ "type": {
174
+ "type": "string",
175
+ "enum": [
176
+ "plain"
177
+ ]
178
+ }
179
+ }
180
+ },
181
+ {
182
+ "type": "object",
183
+ "required": [
184
+ "options",
185
+ "type"
186
+ ],
187
+ "properties": {
188
+ "options": {
189
+ "type": "object",
190
+ "required": [
191
+ "ef_construct",
192
+ "m"
193
+ ],
194
+ "properties": {
195
+ "ef_construct": {
196
+ "type": "integer",
197
+ "format": "uint",
198
+ "minimum": 0.0
199
+ },
200
+ "m": {
201
+ "type": "integer",
202
+ "format": "uint",
203
+ "minimum": 0.0
204
+ }
205
+ }
206
+ },
207
+ "type": {
208
+ "type": "string",
209
+ "enum": [
210
+ "hnsw"
211
+ ]
212
+ }
213
+ }
214
+ }
215
+ ]
216
+ }
217
+ }
218
+ }
tools/sync-web-ui.sh ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+
5
+ STATIC_DIR=${STATIC_DIR:-"./static"}
6
+ OPENAPI_FILE=${OPENAPI_DIR:-"./docs/redoc/master/openapi.json"}
7
+
8
+ # Download `dist.zip` from the latest release of https://github.com/qdrant/qdrant-web-ui and unzip given folder
9
+
10
+ # Get latest dist.zip, assume jq is installed
11
+ DOWNLOAD_LINK=$(curl --silent "https://api.github.com/repos/qdrant/qdrant-web-ui/releases/latest" | jq -r '.assets[] | select(.name=="dist-qdrant.zip") | .browser_download_url')
12
+
13
+ if command -v wget &> /dev/null
14
+ then
15
+ wget -O dist-qdrant.zip $DOWNLOAD_LINK
16
+ else
17
+ curl -L -o dist-qdrant.zip $DOWNLOAD_LINK
18
+ fi
19
+
20
+ rm -rf "${STATIC_DIR}/"*
21
+ unzip -o dist-qdrant.zip -d "${STATIC_DIR}"
22
+ rm dist-qdrant.zip
23
+ cp -r "${STATIC_DIR}/dist/"* "${STATIC_DIR}"
24
+ rm -rf "${STATIC_DIR}/dist"
25
+
26
+ cp "${OPENAPI_FILE}" "${STATIC_DIR}/openapi.json"
tools/update-diagrams.sh ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ # Finds all diagrams in documentation and updates renders
4
+ # Use this script if you updated one of the *.mmd files.
5
+
6
+ # Ensure current path is project root
7
+ cd "$(dirname "$0")/../" || exit
8
+
9
+ find . -name '*.mmd' \
10
+ | xargs -I {} docker run --rm -v $PWD:/data -u $UID ghcr.io/mermaid-js/mermaid-cli/mermaid-cli:latest -i /data/{} -o /data/{}.png
11
+