From 17d0a71bbe1b6e90c78bc32ac49c680e9b57fdba Mon Sep 17 00:00:00 2001 From: Kay Date: Wed, 27 Dec 2023 17:39:06 +0000 Subject: [PATCH] feat: Adding ping command, usage docs and release utils --- .dockerignore | 2 + .github/releaser/release_cli.sh | 44 +++++++++++++++++++++ .github/workflows/docker.yml | 36 +++++++++++++++++ .github/workflows/releaser.yml | 69 +++++++++++++++++++++++++++++++++ Dockerfile | 19 +++++++++ cmd/commands/ping.go | 42 ++++++++++++++++++++ cmd/commands/repl.go | 4 +- cmd/commands/run.go | 6 +-- cmd/commands/util.go | 2 +- cmd/main.go | 3 +- core/TQL/execute/execute.go | 1 + core/database/database.go | 4 ++ core/database/interfaces.go | 1 + core/database/types.go | 1 + doc/TQL/TQL.md | 3 +- doc/usage/.keep | 0 doc/usage/usage.md | 2 + 17 files changed, 231 insertions(+), 8 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/releaser/release_cli.sh create mode 100644 .github/workflows/docker.yml create mode 100644 .github/workflows/releaser.yml create mode 100644 Dockerfile create mode 100644 cmd/commands/ping.go delete mode 100644 doc/usage/.keep create mode 100644 doc/usage/usage.md diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..adafe04 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +.github +build diff --git a/.github/releaser/release_cli.sh b/.github/releaser/release_cli.sh new file mode 100644 index 0000000..1e31417 --- /dev/null +++ b/.github/releaser/release_cli.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Set –e is used within the Bash to stop execution instantly as a query exits +# while having a non-zero status. +set -e + +ROOT_DIR="$(pwd)" +VERSION="$(echo `git -C ${ROOT_DIR} describe --abbrev=0 --tags` | sed 's/^.//')" # "v1.2.3" -> "1.2.3" +PACKAGE_NAME="ttrace_${VERSION}" + + +# https://go.dev/doc/install/source#environment + +for OS_ARCH in \ + "linux amd64" "linux arm64" \ + "android arm64" \ + "freebsd amd64" "freebsd arm" \ + "darwin amd64" "darwin arm64" \ + "windows 386" "windows amd64"; do + + PAIR=($OS_ARCH); + OS=${PAIR[0]}; + ARCH=${PAIR[1]}; + + cd ${ROOT_DIR} + + PACKAGE_NAME_OS=${PACKAGE_NAME}_${OS}_${ARCH} + BUILD_DIR=${ROOT_DIR}/build/${PACKAGE_NAME_OS} + + if [ $OS = "windows" ]; then + EXE=".exe" + fi + + CGO_ENABLED=0 GOOS=${OS} GOARCH=${ARCH} go build -ldflags "-s -w" -trimpath -o ${BUILD_DIR}/${PACKAGE_NAME}/ttrace${EXE} ./cmd/mian.go + + cd ${BUILD_DIR} + if [ $OS = "windows" ]; then + zip -r ${PACKAGE_NAME_OS}.zip ${PACKAGE_NAME} + mv ${PACKAGE_NAME_OS}.zip ${ROOT_DIR} + else + tar -czvf ${PACKAGE_NAME_OS}.tar.gz -p ${PACKAGE_NAME} + mv ${PACKAGE_NAME_OS}.tar.gz ${ROOT_DIR} + fi +done diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..5f44444 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,36 @@ +name: Building Docker and Push to DockerHub + +on: + push: + tags: + - v* + branches: + - main + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v3 + with: + images: pactus/pactus + + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + \ No newline at end of file diff --git a/.github/workflows/releaser.yml b/.github/workflows/releaser.yml new file mode 100644 index 0000000..f7a0dab --- /dev/null +++ b/.github/workflows/releaser.yml @@ -0,0 +1,69 @@ +name: Releaser + +on: + push: + tags: + - v* + +jobs: + ######################################## + build-cli: + runs-on: ubuntu-latest + + # Defining outputs for jobs + # https://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs + outputs: + checksums: ${{ steps.calc_checksums.outputs.checksums }} + + steps: + - uses: actions/checkout@v3 + + - name: Install Dependencies + run: | + sudo apt update + sudo apt install zip + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: 1.21.1 + + - name: Create release files + run: bash ./.github/releasers/releaser_cli.sh + + # Multiline strings in GitHub actions + # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings + - name: Calculate sha256sum + id: calc_checksums + run: | + set -e + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "checksums<<$EOF" >> "$GITHUB_OUTPUT" + echo "$(sha256sum pactus-*.zip pactus-*tar.gz)" >> "$GITHUB_OUTPUT" + echo "$EOF" >> "$GITHUB_OUTPUT" + + - name: Publish + uses: softprops/action-gh-release@v1 + with: + files: | + pactus-*.zip + pactus-*.tar.gz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + + checksums: + needs: [build-cli] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Create SHA256SUMS file + run: | + echo "${{ needs.build-cli.outputs.checksums }}" >> SHA256SUMS + - name: Publish + uses: softprops/action-gh-release@v1 + with: + files: SHA256SUMS + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c9a83fa --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM golang:1.21.5-alpine3.18 as builder + +RUN apk add --no-cache git gmp-dev build-base g++ openssl-dev +ADD . /ttrace + +# Building ttrace-cli +RUN cd /ttrace && \ + go build -ldflags "-s -w" -trimpath -o ./build/ttrace ./cmd/main.go + + +## Copy binary files from builder into second container +FROM golang:1.21.5-alpine3.18 + +COPY --from=builder /timetrace/build/ttrace /usr/bin + +ENV WORKING_DIR "/ttrace" + +VOLUME $WORKING_DIR +WORKDIR $WORKING_DIR diff --git a/cmd/commands/ping.go b/cmd/commands/ping.go new file mode 100644 index 0000000..5116902 --- /dev/null +++ b/cmd/commands/ping.go @@ -0,0 +1,42 @@ +package commands + +import ( + "fmt" + "net" + "os" + + cobra "github.com/spf13/cobra" +) + +func PingCommand(parentCmd *cobra.Command) { + ping := &cobra.Command{ + Use: "ping", + Short: "Ping a remote instance of time trace.", + } + parentCmd.AddCommand(ping) + + address := ping.Flags().StringP("address", "a", "localhost:7070", "remote address of your time trace instance.") + username := ping.Flags().StringP("username", "u", "root", "username of the user you are going to connect with.") + password := ping.Flags().StringP("password", "p", "", "password of user trying to connect with.") + + ping.Run = func(cmd *cobra.Command, args []string) { + conn, err := net.Dial("tcp", *address) + if err != nil { + Dead(cmd, err) + } + defer conn.Close() + + conQuery := fmt.Sprintf("CON %v %v", *username, *password) + + do(conn, conQuery) + + response := do(conn, "PING") + if response == "PONG" { + cmd.Println("PONG, everything is ok.") + os.Exit(0) + } else { + cmd.Printf("something is wrong: %v", response) + os.Exit(1) + } + } +} diff --git a/cmd/commands/repl.go b/cmd/commands/repl.go index d99c2f8..17023bd 100644 --- a/cmd/commands/repl.go +++ b/cmd/commands/repl.go @@ -28,7 +28,7 @@ func REPLCommand(parentCmd *cobra.Command) { connect.Run = func(cmd *cobra.Command, args []string) { conn, err := net.Dial("tcp", *address) if err != nil { - dead(cmd, err) + Dead(cmd, err) } defer conn.Close() @@ -51,7 +51,7 @@ func REPLCommand(parentCmd *cobra.Command) { cmd.Print(do(conn, input)) } } else { - dead(cmd, errors.New(response)) //nolint + Dead(cmd, errors.New(response)) //nolint } } } diff --git a/cmd/commands/run.go b/cmd/commands/run.go index 8b2119e..b9cc659 100644 --- a/cmd/commands/run.go +++ b/cmd/commands/run.go @@ -20,12 +20,12 @@ func RunCommand(parentCmd *cobra.Command) { run.Run = func(cmd *cobra.Command, args []string) { if confingPath == nil || *confingPath == "" { - dead(cmd, tte.ErrInavlidConfigPath) + Dead(cmd, tte.ErrInavlidConfigPath) } cfg, err := config.LoadFromFile(*confingPath) if err != nil { - dead(cmd, err) + Dead(cmd, err) } db := database.Init(cfg) @@ -33,7 +33,7 @@ func RunCommand(parentCmd *cobra.Command) { server := server.NewServer(cfg, db) if err := server.Start(); err != nil { - dead(cmd, err) + Dead(cmd, err) } } } diff --git a/cmd/commands/util.go b/cmd/commands/util.go index 3b7c0ba..e6996f1 100644 --- a/cmd/commands/util.go +++ b/cmd/commands/util.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -func dead(cmd *cobra.Command, err error) { +func Dead(cmd *cobra.Command, err error) { cmd.PrintErrln(err) os.Exit(1) } diff --git a/cmd/main.go b/cmd/main.go index bac612b..f350959 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -14,9 +14,10 @@ func main() { commands.RunCommand(rootCmd) commands.REPLCommand(rootCmd) + commands.PingCommand(rootCmd) err := rootCmd.Execute() if err != nil { - panic(err) + commands.Dead(rootCmd, err) } } diff --git a/core/TQL/execute/execute.go b/core/TQL/execute/execute.go index ff7c0bb..69592ec 100644 --- a/core/TQL/execute/execute.go +++ b/core/TQL/execute/execute.go @@ -9,6 +9,7 @@ type ExecutorMap map[string]Executor var Executors ExecutorMap = ExecutorMap{ "SET": database.IDataBase.AddSet, "CON": database.IDataBase.Connect, + "PING": database.IDataBase.Ping, "SSET": database.IDataBase.AddSubSet, "PUSH": database.IDataBase.PushElement, "DRPS": database.IDataBase.DropSet, diff --git a/core/database/database.go b/core/database/database.go index 531659c..59e0092 100644 --- a/core/database/database.go +++ b/core/database/database.go @@ -45,6 +45,10 @@ func (db *Database) Connect(args []string) string { return INVALID } +func (db *Database) Ping(_ []string) string { + return PONG +} + func (db *Database) AddSet(args []string) string { db.Lock() defer db.Unlock() diff --git a/core/database/interfaces.go b/core/database/interfaces.go index ea0b954..84b43ce 100644 --- a/core/database/interfaces.go +++ b/core/database/interfaces.go @@ -4,6 +4,7 @@ type IDataBase interface { SetsMap() Sets Connect([]string) string + Ping([]string) string AddSet([]string) string AddSubSet([]string) string PushElement([]string) string diff --git a/core/database/types.go b/core/database/types.go index 57e04e0..6d2bab1 100644 --- a/core/database/types.go +++ b/core/database/types.go @@ -9,6 +9,7 @@ import ( const ( INVALID = "INVALID" DONE = "DONE" + PONG = "PONG" SET_NOT_FOUND = "SNF" SUB_SET_NOT_FOUND = "SSNF" ELEMENT_NOT_FOUND = "ENF" diff --git a/doc/TQL/TQL.md b/doc/TQL/TQL.md index 25e671a..39db30b 100644 --- a/doc/TQL/TQL.md +++ b/doc/TQL/TQL.md @@ -9,7 +9,8 @@ Time trace is using a query language called TQL. Here is documentation and speci | Command | Action | Arguments | |----------|:-------------|:------| -| CON | to make a connection and access to database | username - password | +| CON * | to make a connection and access to database | username - password | +| PING * | should send a `PONG` back if everything is ok | | | SET * | make a new set | set-name | | SSET * | make a new subset | set-name - subset-name | | PUSH * | push an element to a subset | set-name - subset-name - value-of-element - time(unix-timestamp) | diff --git a/doc/usage/.keep b/doc/usage/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/doc/usage/usage.md b/doc/usage/usage.md new file mode 100644 index 0000000..c79339a --- /dev/null +++ b/doc/usage/usage.md @@ -0,0 +1,2 @@ +# Usage of time trace +