Skip to content

Commit

Permalink
Version cmd (#179)
Browse files Browse the repository at this point in the history
* Added version command.

* Step

* Step

* remove empty line from output

* more compatible way

Co-authored-by: peb-adr <adrichter97@gmail.com>
  • Loading branch information
normanjaeckel and peb-adr committed Apr 20, 2022
1 parent 1ae0dd6 commit fae51b4
Show file tree
Hide file tree
Showing 8 changed files with 416 additions and 134 deletions.
2 changes: 2 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/OpenSlides/openslides-manage-service/pkg/setpassword"
"github.com/OpenSlides/openslides-manage-service/pkg/setup"
"github.com/OpenSlides/openslides-manage-service/pkg/tunnel"
"github.com/OpenSlides/openslides-manage-service/pkg/version"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -63,6 +64,7 @@ func RootCmd() *cobra.Command {
get.Cmd(),
createuser.Cmd(),
set.Cmd(),
version.Cmd(),
tunnel.Cmd(),
)

Expand Down
7 changes: 7 additions & 0 deletions pkg/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/OpenSlides/openslides-manage-service/pkg/setpassword"
"github.com/OpenSlides/openslides-manage-service/pkg/setup"
"github.com/OpenSlides/openslides-manage-service/pkg/tunnel"
"github.com/OpenSlides/openslides-manage-service/pkg/version"
)

func TestRunClient(t *testing.T) {
Expand Down Expand Up @@ -76,6 +77,12 @@ func TestCmdHelpTexts(t *testing.T) {
outputStartsWith: []byte(set.SetHelp),
},

{
name: "version",
input: []string{"version", "--help"},
outputStartsWith: []byte(version.VersionHelp),
},

{
name: "tunnel command",
input: []string{"tunnel", "--help"},
Expand Down
8 changes: 8 additions & 0 deletions pkg/client/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ func TestSystemInTotal(t *testing.T) {
t.Fatalf("executing command returns error %v", err)
}
})

t.Run("version", func(t *testing.T) {
cmd := client.RootCmd()
cmd.SetArgs([]string{"version", "--password-file", path.Join(dir, "secrets", "manage_auth_password")})
if err := cmd.Execute(); err != nil {
t.Fatalf("executing command returns error %v", err)
}
})
}

func setupTestDir(t testing.TB) string {
Expand Down
15 changes: 15 additions & 0 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/OpenSlides/openslides-manage-service/pkg/setpassword"
"github.com/OpenSlides/openslides-manage-service/pkg/shared"
"github.com/OpenSlides/openslides-manage-service/pkg/tunnel"
"github.com/OpenSlides/openslides-manage-service/pkg/version"
"github.com/OpenSlides/openslides-manage-service/proto"
"golang.org/x/sys/unix"
"google.golang.org/grpc"
Expand Down Expand Up @@ -148,6 +149,10 @@ func (s *srv) Set(ctx context.Context, in *proto.SetRequest) (*proto.SetResponse
return set.Set(ctx, in, a)
}

func (s *srv) Version(ctx context.Context, in *proto.VersionRequest) (*proto.VersionResponse, error) {
return version.Version(ctx, in, s.config.clientVersionURL())
}

func (s *srv) Tunnel(ts proto.Manage_TunnelServer) error {
return tunnel.Tunnel(ts)
}
Expand Down Expand Up @@ -303,6 +308,16 @@ func (c *Config) datastoreReaderURL() *url.URL {
return &u
}

// clientVersionURL returns an URL object to the client service.
func (c *Config) clientVersionURL() *url.URL {
u := url.URL{ // TODO: Protocol, host and port should be retrieved from environment variables.
Scheme: "http",
Host: "client:9001",
Path: "/assets/version.txt",
}
return &u
}

// waitForShutdown blocks until the service exits.
//
// It listens on SIGINT and SIGTERM. If the signal is received for a second
Expand Down
106 changes: 106 additions & 0 deletions pkg/version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package version

import (
"context"
"fmt"
"io"
"net/http"
"net/url"
"strings"

"github.com/OpenSlides/openslides-manage-service/pkg/connection"
"github.com/OpenSlides/openslides-manage-service/proto"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"google.golang.org/grpc/status"
)

const (
// VersionHelp contains the short help text for the command.
VersionHelp = "Retrieves OpenSlides client version tag"

// VersionHelpExtra contains the long help text for the command without
// the headline.
VersionHelpExtra = `The version tag is created during client image build.`
)

// Cmd returns the subcommand.
func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: VersionHelp,
Long: VersionHelp + "\n\n" + VersionHelpExtra,
Args: cobra.NoArgs,
}
cp := connection.Unary(cmd)

cmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), *cp.Timeout)
defer cancel()

cl, close, err := connection.Dial(ctx, *cp.Addr, *cp.PasswordFile, !*cp.NoSSL)
if err != nil {
return fmt.Errorf("connecting to gRPC server: %w", err)
}
defer close()

if err := Run(ctx, cl); err != nil {
return fmt.Errorf("run version call: %w", err)
}
return nil
}
return cmd
}

// Client

type gRPCClient interface {
Version(ctx context.Context, in *proto.VersionRequest, opts ...grpc.CallOption) (*proto.VersionResponse, error)
}

// Run calls respective procedure via given gRPC client.
func Run(ctx context.Context, gc gRPCClient) error {
in := &proto.VersionRequest{}

resp, err := gc.Version(ctx, in)
if err != nil {
s, _ := status.FromError(err) // The ok value does not matter here.
return fmt.Errorf("calling manage service (retrieving version): %s", s.Message())
}

fmt.Println(strings.TrimSpace(resp.Version))
return nil
}

// Server

// Version retrieves the version tag from the client container.
// This function is the server side entrypoint for this package.
func Version(ctx context.Context, in *proto.VersionRequest, clientVersionURL *url.URL) (*proto.VersionResponse, error) {
addr := clientVersionURL.String()
req, err := http.NewRequestWithContext(ctx, "GET", addr, nil)
if err != nil {
return nil, fmt.Errorf("creating request to client service: %w", err)
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("sending request to client service at %q: %w", addr, err)
}
defer resp.Body.Close()

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
body, err := io.ReadAll(resp.Body)
if err != nil {
body = []byte("[can not read body]")
}
return nil, fmt.Errorf("got response %q: %q", resp.Status, body)
}

encodedResp, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("reading response body: %w", err)
}

return &proto.VersionResponse{Version: string(encodedResp)}, nil
}

0 comments on commit fae51b4

Please sign in to comment.