Argh, getting hang of golang and kubernetes. Initial handshake done.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c61a5e8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pb.go
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..698a47b
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,31 @@
+FROM ubuntu:latest
+
+RUN apt-get update --fix-missing
+RUN apt-get -y upgrade
+RUN apt-get -y install wget git bash unzip
+
+WORKDIR /tmp
+RUN wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz
+RUN tar -xvf go1.14.linux-amd64.tar.gz
+RUN mv go /usr/local
+RUN rm go1.14.linux-amd64.tar.gz
+
+ENV GOROOT=/usr/local/go
+ENV GOPATH=/src/go
+ENV GOBIN=$GOPATH/bin
+ENV PATH=$GOBIN:$GOROOT/bin:$PATH
+
+RUN go version
+
+RUN go get -u google.golang.org/grpc
+
+WORKDIR /src/protoc
+RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_64.zip
+RUN unzip protoc-3.11.4-linux-x86_64.zip
+RUN rm protoc-3.11.4-linux-x86_64.zip
+ENV PATH=/src/protoc/bin:$PATH
+
+RUN go get -u github.com/golang/protobuf/protoc-gen-go
+RUN go get -u google.golang.org/protobuf/encoding/prototext
+
+WORKDIR /src/go/src/pcloud
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ab369b6
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# PCloud
diff --git a/chunk/chunk.go b/chunk/chunk.go
new file mode 100644
index 0000000..1dde057
--- /dev/null
+++ b/chunk/chunk.go
@@ -0,0 +1,76 @@
+package main
+
+import "context"
+import "flag"
+import "fmt"
+import "log"
+import "net"
+import "time"
+
+import "google.golang.org/grpc"
+
+import pc "pcloud"
+
+var masterAddress string
+var selfAddress string
+
+func init() {
+ flag.StringVar(&masterAddress, "master", "localhost:123", "Metadata storage address.")
+ flag.StringVar(&selfAddress, "self", "", "Metadata storage address.")
+}
+
+type chunkStorage struct {
+}
+
+func (s *chunkStorage) ListChunks(
+ ctx context.Context,
+ request *pc.ListChunksRequest) (*pc.ListChunksResponse, error) {
+ return nil, nil
+}
+
+func (s *chunkStorage) ReadChunk(
+ ctx context.Context,
+ request *pc.ReadChunkRequest) (*pc.ReadChunkResponse, error) {
+ return nil, nil
+}
+
+func (s *chunkStorage) StoreChunk(
+ ctx context.Context,
+ request *pc.StoreChunkRequest) (*pc.StoreChunkResponse, error) {
+ return nil, nil
+}
+
+func main() {
+ flag.Parse()
+ log.Print("Chunk server starting")
+
+ // Create Master server client.
+ var opts []grpc.DialOption
+ opts = append(opts, grpc.WithInsecure())
+ opts = append(opts, grpc.WithBlock())
+ conn, err := grpc.Dial(masterAddress, opts...)
+ if err != nil {
+ log.Fatalf("Failed to dial %s: %v", masterAddress, err)
+ }
+ defer conn.Close()
+ client := pc.NewMetadataStorageClient(conn)
+
+ // Register current Chunk server with Master.
+ ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
+ _, err = client.AddChunkServer(
+ ctx,
+ &pc.AddChunkServerRequest{Address: selfAddress})
+ if err != nil {
+ log.Fatalf("failed to register chunk server: %v", err)
+ }
+ log.Print("Registered myself")
+
+ // Start RPC server
+ lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 234))
+ if err != nil {
+ log.Fatalf("failed to listen: %v", err)
+ }
+ server := grpc.NewServer()
+ pc.RegisterChunkStorageServer(server, &chunkStorage{})
+ server.Serve(lis)
+}
diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml
new file mode 100644
index 0000000..449013e
--- /dev/null
+++ b/k8s/deployment.yaml
@@ -0,0 +1,78 @@
+---
+kind: Service
+apiVersion: v1
+metadata:
+ name: pcloud-master-service
+spec:
+ type: ClusterIP
+ selector:
+ app: pcloud-master
+ ports:
+ - nodePort:
+ port: 111
+ targetPort: 123
+---
+kind: Deployment
+apiVersion: apps/v1
+metadata:
+ name: pcloud-master
+spec:
+ selector:
+ matchLabels:
+ app: pcloud-master
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: pcloud-master
+ spec:
+ containers:
+ - name: pcloud-master
+ image: pcloud:latest
+ imagePullPolicy: Never
+ ports:
+ - containerPort: 123
+ volumeMounts:
+ - name: code
+ mountPath: /src/go/src/pcloud
+ command: ["/bin/sh"]
+ args: ["-c", "protoc pfs.proto --go_out=plugins=grpc:. && cd master && go install master.go && master --port=123"]
+ volumes:
+ - name: code
+ hostPath:
+ path: "/Users/lekva/dev/src/pcloud"
+---
+kind: Deployment
+apiVersion: apps/v1
+metadata:
+ name: pcloud-chunk
+spec:
+ selector:
+ matchLabels:
+ app: pcloud-chunk
+ replicas: 3
+ template:
+ metadata:
+ labels:
+ app: pcloud-chunk
+ spec:
+ containers:
+ - name: pcloud-chunk
+ image: pcloud:latest
+ imagePullPolicy: Never
+ ports:
+ - containerPort: 234
+ env:
+ - name: SELF_IP
+ valueFrom:
+ fieldRef:
+ fieldPath: status.podIP
+ volumeMounts:
+ - name: code
+ mountPath: /src/go/src/pcloud
+ command: ["/bin/sh"]
+ args: ["-c", "protoc pfs.proto --go_out=plugins=grpc:. && cd chunk && go install chunk.go && chunk --master=pcloud-master-service:111 --self=$(SELF_IP):234"]
+ volumes:
+ - name: code
+ hostPath:
+ path: "/Users/lekva/dev/src/pcloud"
diff --git a/master/core b/master/core
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/master/core
diff --git a/master/master.go b/master/master.go
new file mode 100644
index 0000000..73ac143
--- /dev/null
+++ b/master/master.go
@@ -0,0 +1,60 @@
+package main
+
+import "context"
+import "flag"
+import "fmt"
+import "log"
+import "net"
+
+import "google.golang.org/grpc"
+
+import pc "pcloud"
+
+var port int
+
+func init() {
+ flag.IntVar(&port, "port", 123, "Port to listen on.")
+}
+
+type chunkServer struct {
+ address string
+}
+
+type metadataStorage struct {
+ chunkServer []string
+}
+
+func (s *metadataStorage) AddChunkServer(
+ ctx context.Context,
+ request *pc.AddChunkServerRequest) (*pc.AddChunkServerResponse, error) {
+ s.chunkServer = append(s.chunkServer, request.GetAddress())
+ log.Printf("Registered Chunk server: %s", request.GetAddress())
+ return &pc.AddChunkServerResponse{}, nil
+}
+
+func (s *metadataStorage) CreateBlob(
+ ctx context.Context,
+ request *pc.CreateBlobRequest) (*pc.CreateBlobResponse, error) {
+ return nil, nil
+}
+
+func (s *metadataStorage) GetBlobMetadata(
+ ctx context.Context,
+ request *pc.GetBlobMetadataRequest) (*pc.GetBlobMetadataResponse, error) {
+ return nil, nil
+}
+
+func main() {
+ flag.Parse()
+ log.Print("Master server starting")
+
+ lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
+ if err != nil {
+ log.Fatalf("Failed to listen on port %d: %v", port, err)
+ }
+ log.Printf("Listening on port: %d", port)
+ server := grpc.NewServer()
+ pc.RegisterMetadataStorageServer(server, &metadataStorage{})
+ log.Print("Master serving")
+ server.Serve(lis)
+}
diff --git a/pfs.proto b/pfs.proto
new file mode 100644
index 0000000..4c338f6
--- /dev/null
+++ b/pfs.proto
@@ -0,0 +1,88 @@
+syntax = "proto3";
+
+package pcloud;
+
+message Chunk {
+ string chunk_id = 1;
+ int32 size_bytes = 2;
+ bytes data = 3;
+}
+
+// ChunkStorage
+
+service ChunkStorage {
+ rpc ListChunks(ListChunksRequest) returns (ListChunksResponse) {}
+
+ rpc ReadChunk(ReadChunkRequest) returns (ReadChunkResponse) {}
+
+ rpc StoreChunk(StoreChunkRequest) returns (StoreChunkResponse) {}
+}
+
+message ListChunksRequest {
+}
+
+message ListChunksResponse {
+ repeated string chunk_id = 1;
+}
+
+message ReadChunkRequest {
+ string chunk_id = 1;
+ int32 offset = 2;
+ int32 num_bytes = 3;
+}
+
+message ReadChunkResponse {
+ bytes data = 1;
+}
+
+message StoreChunkRequest {
+ string chunk_id = 1;
+ bytes data = 2;
+}
+
+message StoreChunkResponse {
+}
+
+// MetadataStorage
+
+message ChunkStorageMetadata {
+ string chunk_id = 1;
+ int32 size_bytes = 2;
+ repeated string server = 3;
+}
+
+service MetadataStorage {
+ rpc AddChunkServer(AddChunkServerRequest) returns (AddChunkServerResponse) {}
+
+ rpc CreateBlob(CreateBlobRequest) returns (CreateBlobResponse) {}
+
+ rpc GetBlobMetadata(GetBlobMetadataRequest) returns (GetBlobMetadataResponse) {}
+}
+
+message AddChunkServerRequest {
+ string address = 1;
+}
+
+message AddChunkServerResponse {
+}
+
+message CreateBlobRequest {
+ int32 size_bytes = 1;
+ int32 chunk_size_bytes = 2;
+ int32 num_replicas = 3;
+}
+
+message CreateBlobResponse {
+ string blob_id = 1;
+ repeated ChunkStorageMetadata chunk = 2;
+}
+
+message GetBlobMetadataRequest {
+ string blob_id = 1;
+}
+
+message GetBlobMetadataResponse {
+ string blob_id = 1;
+ int32 size_bytes = 2;
+ repeated ChunkStorageMetadata chunk = 3;
+}
\ No newline at end of file