Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/dev/gpctl/cmd/imagebuilds.go
2498 views
1
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package cmd
6
7
import (
8
"context"
9
"crypto/tls"
10
"crypto/x509"
11
"fmt"
12
"io/ioutil"
13
"net"
14
"path/filepath"
15
16
"github.com/spf13/cobra"
17
"golang.org/x/xerrors"
18
"google.golang.org/grpc"
19
"google.golang.org/grpc/credentials"
20
"google.golang.org/grpc/credentials/insecure"
21
"k8s.io/client-go/kubernetes"
22
23
"github.com/gitpod-io/gitpod/gpctl/pkg/util"
24
"github.com/gitpod-io/gitpod/image-builder/api"
25
)
26
27
// imagebuildsCmd represents the client command
28
var imagebuildsCmd = &cobra.Command{
29
Use: "imagebuilds",
30
Short: "Controls and inspects workspace Docker image builds",
31
Args: cobra.ExactArgs(1),
32
}
33
34
func init() {
35
imagebuildsCmd.PersistentFlags().StringP("tls", "t", "", "TLS certificate when connecting to a secured gRPC endpoint")
36
imagebuildsCmd.PersistentFlags().Bool("mk3", true, "use image-builder mk3")
37
imagebuildsCmd.PersistentFlags().String("host", "", "dial a host directly")
38
imagebuildsCmd.PersistentFlags().String("tls-path", "", "TLS certificate when connecting to a secured gRPC endpoint")
39
40
rootCmd.AddCommand(imagebuildsCmd)
41
}
42
43
func getImagebuildsClient(ctx context.Context) (*grpc.ClientConn, api.ImageBuilderClient, error) {
44
host, _ := imagebuildsCmd.PersistentFlags().GetString("host")
45
if host == "" {
46
cfg, namespace, err := getKubeconfig()
47
if err != nil {
48
return nil, nil, err
49
}
50
clientSet, err := kubernetes.NewForConfig(cfg)
51
if err != nil {
52
return nil, nil, err
53
}
54
55
comp := "image-builder"
56
if mk3, _ := imagebuildsCmd.PersistentFlags().GetBool("mk3"); mk3 {
57
comp = "image-builder-mk3"
58
}
59
60
freePort, err := GetFreePort()
61
if err != nil {
62
return nil, nil, err
63
}
64
65
port := fmt.Sprintf("%d:8080", freePort)
66
podName, err := util.FindAnyPodForComponent(clientSet, namespace, comp)
67
if err != nil {
68
return nil, nil, err
69
}
70
readychan, errchan := util.ForwardPort(ctx, cfg, namespace, podName, port)
71
select {
72
case <-readychan:
73
case err := <-errchan:
74
return nil, nil, err
75
case <-ctx.Done():
76
return nil, nil, ctx.Err()
77
}
78
host = fmt.Sprintf("localhost:%d", freePort)
79
}
80
81
secopt := grpc.WithTransportCredentials(insecure.NewCredentials())
82
cert, _ := imagebuildsCmd.Flags().GetString("tls")
83
if cert != "" {
84
creds, err := credentials.NewClientTLSFromFile(cert, "")
85
if err != nil {
86
return nil, nil, xerrors.Errorf("could not load tls cert: %w", err)
87
}
88
89
secopt = grpc.WithTransportCredentials(creds)
90
} else if fn, _ := imagebuildsCmd.Flags().GetString("tls-path"); fn != "" {
91
crt, err := ioutil.ReadFile(filepath.Join(fn, "tls.crt"))
92
if err != nil {
93
return nil, nil, err
94
}
95
key, err := ioutil.ReadFile(filepath.Join(fn, "tls.key"))
96
if err != nil {
97
return nil, nil, err
98
}
99
cert, err := tls.X509KeyPair(crt, key)
100
if err != nil {
101
return nil, nil, err
102
}
103
104
ca, err := ioutil.ReadFile(filepath.Join(fn, "ca.crt"))
105
if err != nil {
106
return nil, nil, err
107
}
108
certPool := x509.NewCertPool()
109
certPool.AppendCertsFromPEM(ca)
110
111
creds := credentials.NewTLS(&tls.Config{
112
Certificates: []tls.Certificate{cert},
113
RootCAs: certPool,
114
ServerName: "ws-manager",
115
})
116
if err != nil {
117
return nil, nil, xerrors.Errorf("could not load tls cert: %w", err)
118
}
119
120
secopt = grpc.WithTransportCredentials(creds)
121
}
122
123
conn, err := grpc.Dial(host, secopt, util.WithClientUnaryInterceptor())
124
if err != nil {
125
return nil, nil, err
126
}
127
return conn, api.NewImageBuilderClient(conn), nil
128
}
129
130
func GetFreePort() (port int, err error) {
131
var a *net.TCPAddr
132
if a, err = net.ResolveTCPAddr("tcp", "localhost:0"); err == nil {
133
var l *net.TCPListener
134
if l, err = net.ListenTCP("tcp", a); err == nil {
135
defer l.Close()
136
return l.Addr().(*net.TCPAddr).Port, nil
137
}
138
}
139
return
140
}
141
142