mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Move UI out of experimental mode (#7012)
* Make UI not experimental * Display API and UI URLs * Remove link to old sources * Fix integration tests * Add UI to Usage Data * Add a "Using the GUI to edit the Devfile" page to doc * Add link to odo.dev specific page * Apply suggestions from code review Co-authored-by: Armel Soro <armel@rm3l.org> * Change favicon with odo logo * Display web console URL as part of the Dev status * Update UI static files * Document that Comments not supported * Add UI screenshots --------- Co-authored-by: Armel Soro <armel@rm3l.org>
This commit is contained in:
@@ -12,7 +12,9 @@ import (
|
||||
|
||||
openapi "github.com/redhat-developer/odo/pkg/apiserver-gen/go"
|
||||
"github.com/redhat-developer/odo/pkg/apiserver-impl/sse"
|
||||
"github.com/redhat-developer/odo/pkg/informer"
|
||||
"github.com/redhat-developer/odo/pkg/kclient"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/odo/cli/feature"
|
||||
"github.com/redhat-developer/odo/pkg/podman"
|
||||
"github.com/redhat-developer/odo/pkg/preference"
|
||||
@@ -45,6 +47,7 @@ func StartServer(
|
||||
podmanClient podman.Client,
|
||||
stateClient state.Client,
|
||||
preferenceClient preference.Client,
|
||||
informerClient *informer.InformerClient,
|
||||
) (ApiServer, error) {
|
||||
pushWatcher := make(chan struct{})
|
||||
defaultApiService := NewDefaultApiService(
|
||||
@@ -129,7 +132,13 @@ func StartServer(
|
||||
cancelFunc()
|
||||
}
|
||||
|
||||
klog.V(0).Infof("API Server started at localhost:%d/api/v1", listeningPort)
|
||||
if feature.IsEnabled(ctx, feature.UIServer) {
|
||||
info := fmt.Sprintf("Web console accessible at http://localhost:%d/", listeningPort)
|
||||
log.Spinner(info).End(true)
|
||||
informerClient.AppendInfo(info + "\n")
|
||||
}
|
||||
log.Spinner(fmt.Sprintf("API Server started at http://localhost:%d/api/v1", listeningPort)).End(true)
|
||||
log.Spinner(fmt.Sprintf("API documentation accessible at http://localhost:%d/swagger-ui/", listeningPort)).End(true)
|
||||
|
||||
go func() {
|
||||
select {
|
||||
|
||||
BIN
pkg/apiserver-impl/ui/favicon.ico
generated
BIN
pkg/apiserver-impl/ui/favicon.ico
generated
Binary file not shown.
|
Before Width: | Height: | Size: 948 B After Width: | Height: | Size: 15 KiB |
2
pkg/apiserver-impl/ui/index.html
generated
2
pkg/apiserver-impl/ui/index.html
generated
@@ -11,6 +11,6 @@
|
||||
<body class="mat-typography">
|
||||
<div id="loading">Loading, please wait...</div>
|
||||
<app-root></app-root>
|
||||
<script src="runtime.1289ea0acffcdc5e.js" type="module"></script><script src="polyfills.8b3b37cedaf377c3.js" type="module"></script><script src="main.1f6f2714e5bbe400.js" type="module"></script>
|
||||
<script src="runtime.1289ea0acffcdc5e.js" type="module"></script><script src="polyfills.8b3b37cedaf377c3.js" type="module"></script><script src="main.6a89d63885b00552.js" type="module"></script>
|
||||
|
||||
</body></html>
|
||||
1
pkg/apiserver-impl/ui/main.1f6f2714e5bbe400.js
generated
1
pkg/apiserver-impl/ui/main.1f6f2714e5bbe400.js
generated
File diff suppressed because one or more lines are too long
1
pkg/apiserver-impl/ui/main.6a89d63885b00552.js
generated
Normal file
1
pkg/apiserver-impl/ui/main.6a89d63885b00552.js
generated
Normal file
File diff suppressed because one or more lines are too long
@@ -24,13 +24,6 @@ import (
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
const (
|
||||
promptMessage = `
|
||||
[Ctrl+c] - Exit and delete resources from the cluster
|
||||
[p] - Manually apply local changes to the application on the cluster
|
||||
`
|
||||
)
|
||||
|
||||
type DevClient struct {
|
||||
kubernetesClient kclient.ClientInterface
|
||||
prefClient preference.Client
|
||||
@@ -97,7 +90,6 @@ func (o *DevClient) Start(
|
||||
StartOptions: options,
|
||||
DevfileWatchHandler: o.regenerateAdapterAndPush,
|
||||
WatchCluster: true,
|
||||
PromptMessage: promptMessage,
|
||||
}
|
||||
|
||||
return o.watchClient.WatchAndPush(ctx, watchParameters, componentStatus)
|
||||
|
||||
@@ -27,13 +27,6 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
promptMessage = `
|
||||
[Ctrl+c] - Exit and delete resources from podman
|
||||
[p] - Manually apply local changes to the application on podman
|
||||
`
|
||||
)
|
||||
|
||||
type DevClient struct {
|
||||
fs filesystem.Filesystem
|
||||
|
||||
@@ -91,7 +84,6 @@ func (o *DevClient) Start(
|
||||
StartOptions: options,
|
||||
DevfileWatchHandler: o.watchHandler,
|
||||
WatchCluster: false,
|
||||
PromptMessage: promptMessage,
|
||||
}
|
||||
|
||||
return o.watchClient.WatchAndPush(ctx, watchParameters, componentStatus)
|
||||
|
||||
3
pkg/informer/doc.go
Normal file
3
pkg/informer/doc.go
Normal file
@@ -0,0 +1,3 @@
|
||||
// package informer provides a service to register information
|
||||
// to display during Dev mode to the user in a regular basis
|
||||
package informer
|
||||
20
pkg/informer/informer.go
Normal file
20
pkg/informer/informer.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package informer
|
||||
|
||||
type InformerClient struct {
|
||||
info string
|
||||
}
|
||||
|
||||
func NewInformerClient() *InformerClient {
|
||||
return &InformerClient{}
|
||||
}
|
||||
|
||||
func (o *InformerClient) AppendInfo(s string) {
|
||||
if o.info != "" {
|
||||
o.info += "\n"
|
||||
}
|
||||
o.info += s
|
||||
}
|
||||
|
||||
func (o *InformerClient) GetInfo() string {
|
||||
return o.info
|
||||
}
|
||||
@@ -83,6 +83,7 @@ func (o *ApiServerOptions) Run(ctx context.Context) (err error) {
|
||||
nil,
|
||||
o.clientset.StateClient,
|
||||
o.clientset.PreferenceClient,
|
||||
o.clientset.InformerClient,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -119,6 +120,7 @@ func NewCmdApiServer(ctx context.Context, name, fullName string, testClientset c
|
||||
}
|
||||
clientset.Add(apiserverCmd,
|
||||
clientset.FILESYSTEM,
|
||||
clientset.INFORMER,
|
||||
clientset.STATE,
|
||||
clientset.PREFERENCE,
|
||||
)
|
||||
|
||||
@@ -203,10 +203,10 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
|
||||
componentName = odocontext.GetComponentName(ctx)
|
||||
variables = fcontext.GetVariables(ctx)
|
||||
platform = fcontext.GetPlatform(ctx, commonflags.PlatformCluster)
|
||||
dest string
|
||||
deployingTo string
|
||||
)
|
||||
|
||||
var dest string
|
||||
var deployingTo string
|
||||
switch platform {
|
||||
case commonflags.PlatformPodman:
|
||||
dest = "Platform: podman"
|
||||
@@ -286,6 +286,7 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
|
||||
o.clientset.PodmanClient,
|
||||
o.clientset.StateClient,
|
||||
o.clientset.PreferenceClient,
|
||||
o.clientset.InformerClient,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -298,6 +299,10 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
|
||||
}()
|
||||
}
|
||||
|
||||
o.clientset.InformerClient.AppendInfo(log.Sbold("Keyboard Commands:") + "\n" +
|
||||
"[Ctrl+c] - Exit and delete resources from " + deployingTo + "\n" +
|
||||
" [p] - Manually apply local changes to the application on " + deployingTo + "\n")
|
||||
|
||||
return o.clientset.DevClient.Start(
|
||||
o.ctx,
|
||||
dev.StartOptions{
|
||||
@@ -426,6 +431,7 @@ It forwards endpoints with any exposure values ('public', 'internal' or 'none')
|
||||
clientset.DEV,
|
||||
clientset.EXEC,
|
||||
clientset.FILESYSTEM,
|
||||
clientset.INFORMER,
|
||||
clientset.INIT,
|
||||
clientset.KUBERNETES_NULLABLE,
|
||||
clientset.LOGS,
|
||||
|
||||
@@ -19,7 +19,7 @@ var (
|
||||
}
|
||||
|
||||
UIServer = OdoFeature{
|
||||
isExperimental: true,
|
||||
isExperimental: false,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/redhat-developer/odo/pkg/dev/kubedev"
|
||||
"github.com/redhat-developer/odo/pkg/dev/podmandev"
|
||||
"github.com/redhat-developer/odo/pkg/exec"
|
||||
"github.com/redhat-developer/odo/pkg/informer"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/logs"
|
||||
"github.com/redhat-developer/odo/pkg/odo/commonflags"
|
||||
@@ -63,6 +64,8 @@ const (
|
||||
EXEC = "DEP_EXEC"
|
||||
// FILESYSTEM instantiates client for pkg/testingutil/filesystem
|
||||
FILESYSTEM = "DEP_FILESYSTEM"
|
||||
// INFORMER instantiates client for pkg/informer
|
||||
INFORMER = "DEP_INFORMER"
|
||||
// INIT instantiates client for pkg/init
|
||||
INIT = "DEP_INIT"
|
||||
// KUBERNETES_NULLABLE instantiates client for pkg/kclient, can be nil
|
||||
@@ -121,7 +124,7 @@ var subdeps map[string][]string = map[string][]string{
|
||||
REGISTRY: {FILESYSTEM, PREFERENCE, KUBERNETES_NULLABLE},
|
||||
STATE: {FILESYSTEM},
|
||||
SYNC: {EXEC},
|
||||
WATCH: {KUBERNETES_NULLABLE},
|
||||
WATCH: {INFORMER, KUBERNETES_NULLABLE},
|
||||
BINDING: {PROJECT, KUBERNETES_NULLABLE},
|
||||
/* Add sub-dependencies here, if any */
|
||||
}
|
||||
@@ -138,6 +141,7 @@ type Clientset struct {
|
||||
DevClient dev.Client
|
||||
ExecClient exec.Client
|
||||
FS filesystem.Filesystem
|
||||
InformerClient *informer.InformerClient
|
||||
InitClient _init.Client
|
||||
KubernetesClient kclient.ClientInterface
|
||||
LogsClient logs.Client
|
||||
@@ -197,6 +201,9 @@ func Fetch(command *cobra.Command, platform string, testClientset Clientset) (*C
|
||||
dep.FS = filesystem.DefaultFs{}
|
||||
}
|
||||
}
|
||||
if isDefined(command, INFORMER) {
|
||||
dep.InformerClient = informer.NewInformerClient()
|
||||
}
|
||||
if isDefined(command, KUBERNETES) || isDefined(command, KUBERNETES_NULLABLE) {
|
||||
if testClientset.KubernetesClient != nil {
|
||||
dep.KubernetesClient = testClientset.KubernetesClient
|
||||
@@ -293,7 +300,7 @@ func Fetch(command *cobra.Command, platform string, testClientset Clientset) (*C
|
||||
}
|
||||
}
|
||||
if isDefined(command, WATCH) {
|
||||
dep.WatchClient = watch.NewWatchClient(dep.KubernetesClient)
|
||||
dep.WatchClient = watch.NewWatchClient(dep.KubernetesClient, dep.InformerClient)
|
||||
}
|
||||
if isDefined(command, BINDING) {
|
||||
dep.BindingClient = binding.NewBindingClient(dep.ProjectClient, dep.KubernetesClient)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/dev"
|
||||
"github.com/redhat-developer/odo/pkg/dev/common"
|
||||
"github.com/redhat-developer/odo/pkg/informer"
|
||||
|
||||
"github.com/redhat-developer/odo/pkg/kclient"
|
||||
"github.com/redhat-developer/odo/pkg/labels"
|
||||
@@ -36,7 +37,8 @@ const (
|
||||
)
|
||||
|
||||
type WatchClient struct {
|
||||
kubeClient kclient.ClientInterface
|
||||
kubeClient kclient.ClientInterface
|
||||
informerClient *informer.InformerClient
|
||||
|
||||
sourcesWatcher *fsnotify.Watcher
|
||||
deploymentWatcher watch.Interface
|
||||
@@ -55,9 +57,13 @@ type WatchClient struct {
|
||||
|
||||
var _ Client = (*WatchClient)(nil)
|
||||
|
||||
func NewWatchClient(kubeClient kclient.ClientInterface) *WatchClient {
|
||||
func NewWatchClient(
|
||||
kubeClient kclient.ClientInterface,
|
||||
informerClient *informer.InformerClient,
|
||||
) *WatchClient {
|
||||
return &WatchClient{
|
||||
kubeClient: kubeClient,
|
||||
kubeClient: kubeClient,
|
||||
informerClient: informerClient,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +82,6 @@ type WatchParameters struct {
|
||||
|
||||
// WatchCluster indicates to watch Cluster-related objects (Deployment, Pod, etc)
|
||||
WatchCluster bool
|
||||
// PromptMessage
|
||||
PromptMessage string
|
||||
}
|
||||
|
||||
// evaluateChangesFunc evaluates any file changes for the events by ignoring the files in fileIgnores slice and removes
|
||||
@@ -444,14 +448,14 @@ func (o *WatchClient) processEvents(
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(out, "%s - %s\n\n", PushErrorString, err.Error())
|
||||
PrintInfoMessage(out, path, parameters.StartOptions.WatchFiles, parameters.PromptMessage)
|
||||
o.printInfoMessage(out, path, parameters.StartOptions.WatchFiles)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if oldStatus.GetState() != StateReady && componentStatus.GetState() == StateReady ||
|
||||
!reflect.DeepEqual(oldStatus.EndpointsForwarded, componentStatus.EndpointsForwarded) {
|
||||
|
||||
PrintInfoMessage(out, path, parameters.StartOptions.WatchFiles, parameters.PromptMessage)
|
||||
o.printInfoMessage(out, path, parameters.StartOptions.WatchFiles)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -497,7 +501,7 @@ func removeDuplicates(input []string) []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func PrintInfoMessage(out io.Writer, path string, watchFiles bool, promptMessage string) {
|
||||
func (o *WatchClient) printInfoMessage(out io.Writer, path string, watchFiles bool) {
|
||||
log.Sectionf("Dev mode")
|
||||
if watchFiles {
|
||||
fmt.Fprintf(
|
||||
@@ -507,11 +511,9 @@ func PrintInfoMessage(out io.Writer, path string, watchFiles bool, promptMessage
|
||||
path,
|
||||
)
|
||||
}
|
||||
fmt.Fprintf(
|
||||
fmt.Fprint(
|
||||
out,
|
||||
" %s%s",
|
||||
log.Sbold("Keyboard Commands:"),
|
||||
promptMessage,
|
||||
o.informerClient.GetInfo(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user