Echo server
diff --git a/apps/echo/Dockerfile b/apps/echo/Dockerfile
new file mode 100644
index 0000000..cff1435
--- /dev/null
+++ b/apps/echo/Dockerfile
@@ -0,0 +1,4 @@
+FROM alpine:latest
+
+COPY echo /usr/bin
+RUN chmod +x /usr/bin/echo
diff --git a/apps/echo/Makefile b/apps/echo/Makefile
new file mode 100644
index 0000000..3f53cbd
--- /dev/null
+++ b/apps/echo/Makefile
@@ -0,0 +1,18 @@
+build:
+ go build -o echo *.go
+
+clean:
+ rm -f echo
+
+image: clean build
+ docker build --tag=giolekva/echo .
+
+push: image
+ docker push giolekva/echo:latest
+
+
+push_arm64: export GOOS=linux
+push_arm64: export GOARCH=arm64
+push_arm64: export CGO_ENABLED=0
+push_arm64: export GO111MODULE=on
+push_arm64: push
diff --git a/apps/echo/go.mod b/apps/echo/go.mod
new file mode 100644
index 0000000..08142e0
--- /dev/null
+++ b/apps/echo/go.mod
@@ -0,0 +1,3 @@
+module github.com/giolekva/pcloud/apps/echo
+
+go 1.16
diff --git a/apps/echo/install.yaml b/apps/echo/install.yaml
new file mode 100644
index 0000000..b46a5ce
--- /dev/null
+++ b/apps/echo/install.yaml
@@ -0,0 +1,61 @@
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: app-echo
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: echo
+ namespace: app-echo
+spec:
+ type: NodePort
+ selector:
+ app: echo
+ ports:
+ - port: 8080
+ targetPort: 1234
+ protocol: TCP
+ nodePort: 32050
+---
+# apiVersion: traefik.containo.us/v1alpha1
+# kind: IngressRoute
+# metadata:
+# name: ingress
+# namespace: app-echo
+# spec:
+# entryPoints:
+# - web
+# routes:
+# - kind: Rule
+# match: PathPrefix(`/echo`)
+# services:
+# - kind: Service
+# name: echo
+# namespace: app-echo
+# passHostHeader: true
+# port: 80
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: echo
+ namespace: app-echo
+spec:
+ selector:
+ matchLabels:
+ app: echo
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: echo
+ spec:
+ containers:
+ - name: echo
+ image: giolekva/echo:latest
+ imagePullPolicy: Always
+ ports:
+ - containerPort: 1234
+ command: ["echo", "--port=1234"]
diff --git a/apps/echo/main.go b/apps/echo/main.go
new file mode 100644
index 0000000..0e96d2c
--- /dev/null
+++ b/apps/echo/main.go
@@ -0,0 +1,58 @@
+// Copyright 2018 Venil Noronha. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "flag"
+ "fmt"
+ "io"
+ "net"
+ "os"
+)
+
+var port = flag.Int("port", 3000, "Port to listen on")
+
+// main serves as the program entry point
+func main() {
+ flag.Parse()
+ // create a tcp listener on the given port
+ listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
+ if err != nil {
+ fmt.Println("failed to create listener, err:", err)
+ os.Exit(1)
+ }
+ fmt.Printf("listening on %s\n", listener.Addr())
+
+ // listen for new connections
+ for {
+ conn, err := listener.Accept()
+ if err != nil {
+ fmt.Println("failed to accept connection, err:", err)
+ continue
+ }
+
+ // pass an accepted connection to a handler goroutine
+ go handleConnection(conn)
+ }
+}
+
+// handleConnection handles the lifetime of a connection
+func handleConnection(conn net.Conn) {
+ defer conn.Close()
+ reader := bufio.NewReader(conn)
+ for {
+ // read client request data
+ bytes, err := reader.ReadBytes(byte('\n'))
+ if err != nil {
+ if err != io.EOF {
+ fmt.Println("failed to read data, err:", err)
+ }
+ return
+ }
+ fmt.Printf("request: %s", bytes)
+ conn.Write(bytes)
+ }
+}