diff --git a/docker-compose.yaml b/docker-compose.yaml index c4bd72e..b1a8218 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -18,11 +18,11 @@ services: - PLUGIN_DIR=/usr/local/lib/echovault - DATA_DIR=/var/lib/echovault - IN_MEMORY=false - - TLS=true - - MTLS=true + - TLS=false + - MTLS=false - BOOTSTRAP_CLUSTER=false - ACL_CONFIG=/etc/config/echovault/acl.yml - - REQUIRE_PASS=true + - REQUIRE_PASS=false - PASSWORD=default_password - FORWARD_COMMAND=false - SNAPSHOT_THRESHOLD=1000 @@ -45,206 +45,206 @@ services: networks: - testnet - cluster_node_1: - container_name: cluster_node_1 - build: - context: . - dockerfile: Dockerfile.dev - environment: - - PORT=7480 - - RAFT_PORT=8000 - - ML_PORT=7946 - - KEY=/etc/ssl/certs/echovault/server1.key - - CERT=/etc/ssl/certs/echovault/server1.crt - - SERVER_ID=1 - - DATA_DIR=/var/lib/echovault - - IN_MEMORY=false - - TLS=true - - MTLS=true - - BOOTSTRAP_CLUSTER=true - - ACL_CONFIG=/etc/config/echovault/acl.yml - - REQUIRE_PASS=false - - FORWARD_COMMAND=true - - SNAPSHOT_THRESHOLD=1000 - - SNAPSHOT_INTERVAL=5m30s - - RESTORE_SNAPSHOT=false - - RESTORE_AOF=false - - AOF_SYNC_STRATEGY=everysec - # List of server cert/key pairs - - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key - - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key - # List of client certificate authorities - - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt - ports: - - "7480:7480" - - "7945:7946" - - "8000:8000" - volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml - - ./volumes/cluster_node_1:/var/lib/echovault - networks: - - testnet - - cluster_node_2: - container_name: cluster_node_2 - build: - context: . - dockerfile: Dockerfile.dev - environment: - - PORT=7480 - - RAFT_PORT=8000 - - ML_PORT=7946 - - KEY=/etc/ssl/certs/echovault/server1.key - - CERT=/etc/ssl/certs/echovault/server1.crt - - SERVER_ID=2 - - JOIN_ADDR=cluster_node_1:7946 - - DATA_DIR=/var/lib/echovault - - IN_MEMORY=false - - TLS=true - - MTLS=true - - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml - - REQUIRE_PASS=false - - FORWARD_COMMAND=true - - SNAPSHOT_THRESHOLD=1000 - - SNAPSHOT_INTERVAL=5m30s - - RESTORE_SNAPSHOT=false - - RESTORE_AOF=false - - AOF_SYNC_STRATEGY=everysec - # List of server cert/key pairs - - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key - - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key - # List of client certificate authorities - - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt - ports: - - "7481:7480" - - "7947:7946" - - "8001:8000" - volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml - - ./volumes/cluster_node_2:/var/lib/echovault - networks: - - testnet - - cluster_node_3: - container_name: cluster_node_3 - build: - context: . - dockerfile: Dockerfile.dev - environment: - - PORT=7480 - - RAFT_PORT=8000 - - ML_PORT=7946 - - KEY=/etc/ssl/certs/echovault/server1.key - - CERT=/etc/ssl/certs/echovault/server1.crt - - SERVER_ID=3 - - JOIN_ADDR=cluster_node_1:7946 - - DATA_DIR=/var/lib/echovault - - IN_MEMORY=false - - TLS=true - - MTLS=true - - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml - - REQUIRE_PASS=false - - FORWARD_COMMAND=true - - SNAPSHOT_THRESHOLD=1000 - - SNAPSHOT_INTERVAL=5m30s - - RESTORE_SNAPSHOT=false - - RESTORE_AOF=false - - AOF_SYNC_STRATEGY=everysec - # List of server cert/key pairs - - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key - - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key - # List of client certificate authorities - - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt - ports: - - "7482:7480" - - "7948:7946" - - "8002:8000" - volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml - - ./volumes/cluster_node_3:/var/lib/echovault - networks: - - testnet - - cluster_node_4: - container_name: cluster_node_4 - build: - context: . - dockerfile: Dockerfile.dev - environment: - - PORT=7480 - - RAFT_PORT=8000 - - ML_PORT=7946 - - KEY=/etc/ssl/certs/echovault/server1.key - - CERT=/etc/ssl/certs/echovault/server1.crt - - SERVER_ID=4 - - JOIN_ADDR=cluster_node_1:7946 - - DATA_DIR=/var/lib/echovault - - IN_MEMORY=false - - TLS=true - - MTLS=true - - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml - - REQUIRE_PASS=false - - FORWARD_COMMAND=true - - SNAPSHOT_THRESHOLD=1000 - - SNAPSHOT_INTERVAL=5m30s - - RESTORE_SNAPSHOT=false - - RESTORE_AOF=false - - AOF_SYNC_STRATEGY=everysec - # List of server cert/key pairs - - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key - - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key - # List of client certificate authorities - - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt - ports: - - "7483:7480" - - "7949:7946" - - "8003:8000" - volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml - - ./volumes/cluster_node_4:/var/lib/echovault - networks: - - testnet - - cluster_node_5: - container_name: cluster_node_5 - build: - context: . - dockerfile: Dockerfile.dev - environment: - - PORT=7480 - - RAFT_PORT=8000 - - ML_PORT=7946 - - KEY=/etc/ssl/certs/echovault/server1.key - - CERT=/etc/ssl/certs/echovault/server1.crt - - SERVER_ID=5 - - JOIN_ADDR=cluster_node_1:7946 - - DATA_DIR=/var/lib/echovault - - IN_MEMORY=false - - TLS=true - - MTLS=true - - BOOTSTRAP_CLUSTER=false - - ACL_CONFIG=/etc/config/echovault/acl.yml - - REQUIRE_PASS=false - - FORWARD_COMMAND=true - - SNAPSHOT_THRESHOLD=1000 - - SNAPSHOT_INTERVAL=5m30s - - RESTORE_SNAPSHOT=false - - RESTORE_AOF=false - - AOF_SYNC_STRATEGY=everysec - # List of server cert/key pairs - - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key - - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key - # List of client certificate authorities - - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt - ports: - - "7484:7480" - - "7950:7946" - - "8004:8000" - volumes: - - ./config/acl.yml:/etc/config/echovault/acl.yml - - ./volumes/cluster_node_5:/var/lib/echovault - networks: - - testnet \ No newline at end of file +# cluster_node_1: +# container_name: cluster_node_1 +# build: +# context: . +# dockerfile: Dockerfile.dev +# environment: +# - PORT=7480 +# - RAFT_PORT=8000 +# - ML_PORT=7946 +# - KEY=/etc/ssl/certs/echovault/server1.key +# - CERT=/etc/ssl/certs/echovault/server1.crt +# - SERVER_ID=1 +# - DATA_DIR=/var/lib/echovault +# - IN_MEMORY=false +# - TLS=true +# - MTLS=true +# - BOOTSTRAP_CLUSTER=true +# - ACL_CONFIG=/etc/config/echovault/acl.yml +# - REQUIRE_PASS=false +# - FORWARD_COMMAND=true +# - SNAPSHOT_THRESHOLD=1000 +# - SNAPSHOT_INTERVAL=5m30s +# - RESTORE_SNAPSHOT=false +# - RESTORE_AOF=false +# - AOF_SYNC_STRATEGY=everysec +# # List of server cert/key pairs +# - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key +# - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key +# # List of client certificate authorities +# - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt +# ports: +# - "7480:7480" +# - "7945:7946" +# - "8000:8000" +# volumes: +# - ./config/acl.yml:/etc/config/echovault/acl.yml +# - ./volumes/cluster_node_1:/var/lib/echovault +# networks: +# - testnet +# +# cluster_node_2: +# container_name: cluster_node_2 +# build: +# context: . +# dockerfile: Dockerfile.dev +# environment: +# - PORT=7480 +# - RAFT_PORT=8000 +# - ML_PORT=7946 +# - KEY=/etc/ssl/certs/echovault/server1.key +# - CERT=/etc/ssl/certs/echovault/server1.crt +# - SERVER_ID=2 +# - JOIN_ADDR=cluster_node_1:7946 +# - DATA_DIR=/var/lib/echovault +# - IN_MEMORY=false +# - TLS=true +# - MTLS=true +# - BOOTSTRAP_CLUSTER=false +# - ACL_CONFIG=/etc/config/echovault/acl.yml +# - REQUIRE_PASS=false +# - FORWARD_COMMAND=true +# - SNAPSHOT_THRESHOLD=1000 +# - SNAPSHOT_INTERVAL=5m30s +# - RESTORE_SNAPSHOT=false +# - RESTORE_AOF=false +# - AOF_SYNC_STRATEGY=everysec +# # List of server cert/key pairs +# - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key +# - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key +# # List of client certificate authorities +# - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt +# ports: +# - "7481:7480" +# - "7947:7946" +# - "8001:8000" +# volumes: +# - ./config/acl.yml:/etc/config/echovault/acl.yml +# - ./volumes/cluster_node_2:/var/lib/echovault +# networks: +# - testnet +# +# cluster_node_3: +# container_name: cluster_node_3 +# build: +# context: . +# dockerfile: Dockerfile.dev +# environment: +# - PORT=7480 +# - RAFT_PORT=8000 +# - ML_PORT=7946 +# - KEY=/etc/ssl/certs/echovault/server1.key +# - CERT=/etc/ssl/certs/echovault/server1.crt +# - SERVER_ID=3 +# - JOIN_ADDR=cluster_node_1:7946 +# - DATA_DIR=/var/lib/echovault +# - IN_MEMORY=false +# - TLS=true +# - MTLS=true +# - BOOTSTRAP_CLUSTER=false +# - ACL_CONFIG=/etc/config/echovault/acl.yml +# - REQUIRE_PASS=false +# - FORWARD_COMMAND=true +# - SNAPSHOT_THRESHOLD=1000 +# - SNAPSHOT_INTERVAL=5m30s +# - RESTORE_SNAPSHOT=false +# - RESTORE_AOF=false +# - AOF_SYNC_STRATEGY=everysec +# # List of server cert/key pairs +# - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key +# - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key +# # List of client certificate authorities +# - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt +# ports: +# - "7482:7480" +# - "7948:7946" +# - "8002:8000" +# volumes: +# - ./config/acl.yml:/etc/config/echovault/acl.yml +# - ./volumes/cluster_node_3:/var/lib/echovault +# networks: +# - testnet +# +# cluster_node_4: +# container_name: cluster_node_4 +# build: +# context: . +# dockerfile: Dockerfile.dev +# environment: +# - PORT=7480 +# - RAFT_PORT=8000 +# - ML_PORT=7946 +# - KEY=/etc/ssl/certs/echovault/server1.key +# - CERT=/etc/ssl/certs/echovault/server1.crt +# - SERVER_ID=4 +# - JOIN_ADDR=cluster_node_1:7946 +# - DATA_DIR=/var/lib/echovault +# - IN_MEMORY=false +# - TLS=true +# - MTLS=true +# - BOOTSTRAP_CLUSTER=false +# - ACL_CONFIG=/etc/config/echovault/acl.yml +# - REQUIRE_PASS=false +# - FORWARD_COMMAND=true +# - SNAPSHOT_THRESHOLD=1000 +# - SNAPSHOT_INTERVAL=5m30s +# - RESTORE_SNAPSHOT=false +# - RESTORE_AOF=false +# - AOF_SYNC_STRATEGY=everysec +# # List of server cert/key pairs +# - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key +# - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key +# # List of client certificate authorities +# - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt +# ports: +# - "7483:7480" +# - "7949:7946" +# - "8003:8000" +# volumes: +# - ./config/acl.yml:/etc/config/echovault/acl.yml +# - ./volumes/cluster_node_4:/var/lib/echovault +# networks: +# - testnet +# +# cluster_node_5: +# container_name: cluster_node_5 +# build: +# context: . +# dockerfile: Dockerfile.dev +# environment: +# - PORT=7480 +# - RAFT_PORT=8000 +# - ML_PORT=7946 +# - KEY=/etc/ssl/certs/echovault/server1.key +# - CERT=/etc/ssl/certs/echovault/server1.crt +# - SERVER_ID=5 +# - JOIN_ADDR=cluster_node_1:7946 +# - DATA_DIR=/var/lib/echovault +# - IN_MEMORY=false +# - TLS=true +# - MTLS=true +# - BOOTSTRAP_CLUSTER=false +# - ACL_CONFIG=/etc/config/echovault/acl.yml +# - REQUIRE_PASS=false +# - FORWARD_COMMAND=true +# - SNAPSHOT_THRESHOLD=1000 +# - SNAPSHOT_INTERVAL=5m30s +# - RESTORE_SNAPSHOT=false +# - RESTORE_AOF=false +# - AOF_SYNC_STRATEGY=everysec +# # List of server cert/key pairs +# - CERT_KEY_PAIR_1=/etc/ssl/certs/echovault/server/server1.crt,/etc/ssl/certs/echovault/server/server1.key +# - CERT_KEY_PAIR_2=/etc/ssl/certs/echovault/server/server2.crt,/etc/ssl/certs/echovault/server/server2.key +# # List of client certificate authorities +# - CLIENT_CA_1=/etc/ssl/certs/echovault/client/rootCA.crt +# ports: +# - "7484:7480" +# - "7950:7946" +# - "8004:8000" +# volumes: +# - ./config/acl.yml:/etc/config/echovault/acl.yml +# - ./volumes/cluster_node_5:/var/lib/echovault +# networks: +# - testnet \ No newline at end of file diff --git a/dump.rdb b/dump.rdb new file mode 100644 index 0000000..347cc4b Binary files /dev/null and b/dump.rdb differ diff --git a/src/modules/admin/commands.go b/src/modules/admin/commands.go index 4e80b00..e718363 100644 --- a/src/modules/admin/commands.go +++ b/src/modules/admin/commands.go @@ -48,11 +48,35 @@ func handleGetAllCommands(ctx context.Context, cmd []string, server utils.Server } } - res = fmt.Sprintf("*%d\r\n%s\r\n", commandCount, res) + res = fmt.Sprintf("*%d\r\n%s", commandCount, res) return []byte(res), nil } +func handleCommandDocs(ctx context.Context, cmd []string, server utils.Server, _ *net.Conn) ([]byte, error) { + return []byte("*0\r\n"), nil +} + +func handleCommandCount(ctx context.Context, cmd []string, server utils.Server, _ *net.Conn) ([]byte, error) { + return nil, errors.New("command not yet implemented") +} + +func handleCommandList(ctx context.Context, cmd []string, server utils.Server, _ *net.Conn) ([]byte, error) { + return nil, errors.New("command not yet implemented") +} + +func handleConfigGet(ctx context.Context, cmd []string, server utils.Server, _ *net.Conn) ([]byte, error) { + return nil, errors.New("command not yet implemented") +} + +func handleConfigRewrite(ctx context.Context, cmd []string, server *utils.Server, _ *net.Conn) ([]byte, error) { + return nil, errors.New("command not yet implemented") +} + +func handleConfigSet(ctx context.Context, cmd []string, server *utils.Server, _ *net.Conn) ([]byte, error) { + return nil, errors.New("command not yet implemented") +} + func Commands() []utils.Command { return []utils.Command{ { @@ -63,6 +87,25 @@ func Commands() []utils.Command { KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil }, HandlerFunc: handleGetAllCommands, }, + { + Command: "command", + Categories: []string{}, + Description: "Commands pertaining to echovault commands", + Sync: false, + KeyExtractionFunc: func(cmd []string) ([]string, error) { + return []string{}, nil + }, + SubCommands: []utils.SubCommand{ + { + Command: "docs", + Categories: []string{utils.SlowCategory, utils.ConnectionCategory}, + Description: "Get command documentation", + Sync: false, + KeyExtractionFunc: func(cmd []string) ([]string, error) { return []string{}, nil }, + HandlerFunc: handleCommandDocs, + }, + }, + }, { Command: "save", Categories: []string{utils.AdminCategory, utils.SlowCategory, utils.DangerousCategory}, diff --git a/src/modules/etc/commands.go b/src/modules/etc/commands.go index 4e8993f..266663f 100644 --- a/src/modules/etc/commands.go +++ b/src/modules/etc/commands.go @@ -2,6 +2,7 @@ package etc import ( "context" + "errors" "fmt" "github.com/echovault/echovault/src/utils" "net" @@ -50,9 +51,7 @@ func handleSetNX(ctx context.Context, cmd []string, server utils.Server, conn *n if server.KeyExists(key) { return nil, fmt.Errorf("key %s already exists", key) } - // TODO: Retry CreateKeyAndLock until we manage to obtain the key - _, err = server.CreateKeyAndLock(ctx, key) - if err != nil { + if _, err = server.CreateKeyAndLock(ctx, key); err != nil { return nil, err } server.SetValue(ctx, key, utils.AdaptType(cmd[2])) @@ -115,6 +114,10 @@ func handleMSet(ctx context.Context, cmd []string, server utils.Server, conn *ne return []byte(utils.OK_RESPONSE), nil } +func handleCopy(ctx context.Context, cmd []string, server *utils.Server, _ *net.Conn) ([]byte, error) { + return nil, errors.New("command not yet implemented") +} + func Commands() []utils.Command { return []utils.Command{ { diff --git a/src/modules/get/commands.go b/src/modules/get/commands.go index ddc3679..17c703f 100644 --- a/src/modules/get/commands.go +++ b/src/modules/get/commands.go @@ -15,7 +15,7 @@ func handleGet(ctx context.Context, cmd []string, server utils.Server, conn *net key := keys[0] if !server.KeyExists(key) { - return []byte("+nil\r\n\r\n"), nil + return []byte("$-1\r\n"), nil } _, err = server.KeyRLock(ctx, key) @@ -26,7 +26,7 @@ func handleGet(ctx context.Context, cmd []string, server utils.Server, conn *net value := server.GetValue(key) - return []byte(fmt.Sprintf("+%v\r\n\r\n", value)), nil + return []byte(fmt.Sprintf("+%v\r\n", value)), nil } func handleMGet(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) { @@ -72,8 +72,6 @@ func handleMGet(ctx context.Context, cmd []string, server utils.Server, conn *ne bytes = append(bytes, []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(values[key]), values[key]))...) } - bytes = append(bytes, []byte("\r\n")...) - return bytes, nil } diff --git a/src/modules/ping/commands.go b/src/modules/ping/commands.go index 4779d53..2683f1e 100644 --- a/src/modules/ping/commands.go +++ b/src/modules/ping/commands.go @@ -13,9 +13,9 @@ func handlePing(ctx context.Context, cmd []string, server utils.Server, conn *ne default: return nil, errors.New(utils.WRONG_ARGS_RESPONSE) case 1: - return []byte("+PONG\r\n\r\n"), nil + return []byte("+PONG\r\n"), nil case 2: - return []byte(fmt.Sprintf("$%d\r\n%s\r\n\r\n", len(cmd[1]), cmd[1])), nil + return []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(cmd[1]), cmd[1])), nil } } @@ -40,7 +40,7 @@ func Commands() []utils.Command { return []string{}, nil }, HandlerFunc: func(ctx context.Context, cmd []string, server utils.Server, conn *net.Conn) ([]byte, error) { - return []byte("$-1\r\n\r\n"), nil + return []byte("$-1\r\n"), nil }, }, } diff --git a/src/server/server.go b/src/server/server.go index 5002372..7a2e507 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -208,6 +208,7 @@ func (server *Server) handleConnection(ctx context.Context, conn net.Conn) { if err != nil && errors.Is(err, io.EOF) { // Connection closed + log.Println(err) break } @@ -219,7 +220,7 @@ func (server *Server) handleConnection(ctx context.Context, conn net.Conn) { res, err := server.handleCommand(ctx, message, &conn, false) if err != nil { - if _, err = w.Write([]byte(fmt.Sprintf("-Error %s\r\n\r\n", err.Error()))); err != nil { + if _, err = w.Write([]byte(fmt.Sprintf("-Error %s\r\n", err.Error()))); err != nil { log.Println(err) } continue diff --git a/src/utils/const.go b/src/utils/const.go index b7418c8..2c7b5c7 100644 --- a/src/utils/const.go +++ b/src/utils/const.go @@ -25,6 +25,6 @@ const ( ) const ( - OK_RESPONSE = "+OK\r\n\r\n" + OK_RESPONSE = "+OK\r\n" WRONG_ARGS_RESPONSE = "wrong number of arguments" )