Skip to content

Commit

Permalink
feat(gateway): allow tenant to recover manifest of active lease (#251)
Browse files Browse the repository at this point in the history
refs akash-network/support#227

---------

Signed-off-by: Artur Troian <[email protected]>
  • Loading branch information
troian authored Oct 29, 2024
1 parent 83484f2 commit 1b957e8
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 9 deletions.
8 changes: 8 additions & 0 deletions _run/common-commands.mk
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ send-manifest:
--from "$(KEY_NAME)" \
--provider "$(PROVIDER_ADDRESS)"

.PHONY: get-manifest
get-manifest:
$(PROVIDER_SERVICES) get-manifest \
--dseq "$(DSEQ)" \
--from "$(KEY_NAME)" \
--provider "$(PROVIDER_ADDRESS)"


.PHONY: deployment-create
deployment-create:
$(AKASH) tx deployment create "$(SDL_PATH)" \
Expand Down
35 changes: 35 additions & 0 deletions cmd/provider-services/cmd/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,41 @@ func dseqFromFlags(flags *pflag.FlagSet) (uint64, error) {
return flags.GetUint64(FlagDSeq)
}

func leaseIDFromFlags(cflags *pflag.FlagSet, owner string) (mtypes.LeaseID, error) {
str, err := cflags.GetString(FlagProvider)
if err != nil {
return mtypes.LeaseID{}, err
}

provider, err := sdk.AccAddressFromBech32(str)
if err != nil {
return mtypes.LeaseID{}, err
}

dseq, err := cflags.GetUint64(FlagDSeq)
if err != nil {
return mtypes.LeaseID{}, err
}

gseq, err := cflags.GetUint32(FlagGSeq)
if err != nil {
return mtypes.LeaseID{}, err
}

oseq, err := cflags.GetUint32(FlagOSeq)
if err != nil {
return mtypes.LeaseID{}, err
}

return mtypes.LeaseID{
Owner: owner,
DSeq: dseq,
GSeq: gseq,
OSeq: oseq,
Provider: provider.String(),
}, nil
}

func providerFromFlags(flags *pflag.FlagSet) (sdk.Address, error) {
provider, err := flags.GetString(FlagProvider)
if err != nil {
Expand Down
78 changes: 78 additions & 0 deletions cmd/provider-services/cmd/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ var (
errSubmitManifestFailed = errors.New("submit manifest to some providers has been failed")
)

func ManifestCmds() []*cobra.Command {
return []*cobra.Command{
SendManifestCmd(),
GetManifestCmd(),
}
}

// SendManifestCmd looks up the Providers blockchain information,
// and POSTs the SDL file to the Gateway address.
func SendManifestCmd() *cobra.Command {
Expand All @@ -45,6 +52,77 @@ func SendManifestCmd() *cobra.Command {
return cmd
}

// GetManifestCmd reads current manifest from the provider
func GetManifestCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "get-manifest",
Args: cobra.ExactArgs(0),
Short: "Read manifest from provider",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {

Check failure on line 62 in cmd/provider-services/cmd/manifest.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'args' seems to be unused, consider removing or renaming it as _ (revive)
cctx, err := sdkclient.GetClientTxContext(cmd)
if err != nil {
return err
}

ctx := cmd.Context()

cl, err := aclient.DiscoverQueryClient(ctx, cctx)
if err != nil {
return err
}

cert, err := cutils.LoadAndQueryCertificateForAccount(cmd.Context(), cctx, nil)
if err != nil {
return markRPCServerError(err)
}

lid, err := leaseIDFromFlags(cmd.Flags(), cctx.GetFromAddress().String())
if err != nil {
return err
}

prov, _ := sdk.AccAddressFromBech32(lid.Provider)
gclient, err := gwrest.NewClient(ctx, cl, prov, []tls.Certificate{cert})
if err != nil {
return err
}

mani, err := gclient.GetManifest(ctx, lid)
if err != nil {
return err
}

buf := &bytes.Buffer{}

switch cmd.Flag(flagOutput).Value.String() {
case outputJSON:
err = json.NewEncoder(buf).Encode(mani)
case outputYAML:
err = yaml.NewEncoder(buf).Encode(mani)
}

if err != nil {
return err
}

_, err = fmt.Fprint(cmd.OutOrStdout(), buf.String())

if err != nil {
return err
}

return nil
},
}

addLeaseFlags(cmd)

cmd.Flags().StringP(flagOutput, "o", outputYAML, "output format json|yaml. default yaml")

return cmd
}

func doSendManifest(cmd *cobra.Command, sdlpath string) error {
cctx, err := sdkclient.GetClientTxContext(cmd)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/provider-services/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func NewRootCmd() *cobra.Command {
return nil
}

cmd.AddCommand(SendManifestCmd())
cmd.AddCommand(ManifestCmds()...)
cmd.AddCommand(statusCmd())
cmd.AddCommand(leaseStatusCmd())
cmd.AddCommand(leaseEventsCmd())
Expand Down
41 changes: 41 additions & 0 deletions gateway/rest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type Client interface {
Status(ctx context.Context) (*provider.Status, error)
Validate(ctx context.Context, gspec dtypes.GroupSpec) (provider.ValidateGroupSpecResult, error)
SubmitManifest(ctx context.Context, dseq uint64, mani manifest.Manifest) error
GetManifest(ctx context.Context, id mtypes.LeaseID) (manifest.Manifest, error)
LeaseStatus(ctx context.Context, id mtypes.LeaseID) (LeaseStatus, error)
LeaseEvents(ctx context.Context, id mtypes.LeaseID, services string, follow bool) (*LeaseKubeEvents, error)
LeaseLogs(ctx context.Context, id mtypes.LeaseID, services string, follow bool, tailLines int64) (*ServiceLogs, error)
Expand Down Expand Up @@ -425,6 +426,46 @@ func (c *client) SubmitManifest(ctx context.Context, dseq uint64, mani manifest.
return createClientResponseErrorIfNotOK(resp, responseBuf)
}

func (c *client) GetManifest(ctx context.Context, lid mtypes.LeaseID) (manifest.Manifest, error) {
uri, err := makeURI(c.host, getManifestPath(lid))
if err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, "GET", uri, nil)
if err != nil {
return nil, err
}

rCl := c.newReqClient(ctx)
resp, err := rCl.hclient.Do(req)

if err != nil {
return nil, err
}

defer func() {
_ = resp.Body.Close()
}()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

err = createClientResponseErrorIfNotOK(resp, bytes.NewBuffer(body))
if err != nil {
return nil, err
}

var mani manifest.Manifest
if err = json.Unmarshal(body, &mani); err != nil {
return nil, err
}

return mani, nil
}

func (c *client) MigrateEndpoints(ctx context.Context, endpoints []string, dseq uint64, gseq uint32) error {
uri, err := makeURI(c.host, "endpoint/migrate")
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions gateway/rest/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func submitManifestPath(dseq uint64) string {
return fmt.Sprintf("deployment/%d/manifest", dseq)
}

func getManifestPath(id mtypes.LeaseID) string {
return fmt.Sprintf("%s/manifest", leasePath(id))
}

func leaseStatusPath(id mtypes.LeaseID) string {
return fmt.Sprintf("%s/status", leasePath(id))
}
Expand Down
40 changes: 35 additions & 5 deletions gateway/rest/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,23 @@ func newRouter(log log.Logger, addr sdk.Address, pclient provider.Client, ctxCon

hostnameRouter := router.PathPrefix(hostnamePrefix).Subrouter()
hostnameRouter.Use(requireOwner())
hostnameRouter.HandleFunc(migratePathPrefix, migrateHandler(log, pclient.Hostname(), pclient.ClusterService())).
hostnameRouter.HandleFunc(migratePathPrefix,
migrateHandler(log, pclient.Hostname(), pclient.ClusterService())).
Methods(http.MethodPost)

endpointRouter := router.PathPrefix(endpointPrefix).Subrouter()
endpointRouter.Use(requireOwner())
endpointRouter.HandleFunc(migratePathPrefix, migrateEndpointHandler(log, pclient.ClusterService(), pclient.Cluster())).
endpointRouter.HandleFunc(migratePathPrefix,
migrateEndpointHandler(log, pclient.ClusterService(), pclient.Cluster())).
Methods(http.MethodPost)

// PUT /deployment/manifest
drouter := router.PathPrefix(deploymentPathPrefix).Subrouter()
drouter.Use(
requireOwner(),
requireDeploymentID(),
)

// PUT /deployment/manifest
drouter.HandleFunc("/manifest",
createManifestHandler(log, pclient.Manifest())).
Methods(http.MethodPut)
Expand All @@ -152,6 +154,11 @@ func newRouter(log log.Logger, addr sdk.Address, pclient provider.Client, ctxCon
requireLeaseID(),
)

// GET /lease/<lease-id>/manifest
lrouter.HandleFunc("/manifest",
getManifestHandler(log, pclient.Cluster())).
Methods(http.MethodGet)

// GET /lease/<lease-id>/status
lrouter.HandleFunc("/status",
leaseStatusHandler(log, pclient.Cluster(), ctxConfig)).
Expand Down Expand Up @@ -188,7 +195,7 @@ func newRouter(log log.Logger, addr sdk.Address, pclient provider.Client, ctxCon

// POST /lease/<lease-id>/shell
lrouter.HandleFunc("/shell",
leaseShellHandler(log, pclient.Manifest(), pclient.Cluster()))
leaseShellHandler(log, pclient.Cluster()))

return router
}
Expand Down Expand Up @@ -306,7 +313,7 @@ type leaseShellResponse struct {
Message string `json:"message,omitempty"`
}

func leaseShellHandler(log log.Logger, mclient pmanifest.Client, cclient cluster.Client) http.HandlerFunc {
func leaseShellHandler(log log.Logger, cclient cluster.Client) http.HandlerFunc {
return func(rw http.ResponseWriter, req *http.Request) {
leaseID := requestLeaseID(req)

Expand Down Expand Up @@ -591,6 +598,29 @@ func createManifestHandler(log log.Logger, mclient pmanifest.Client) http.Handle
}
}

func getManifestHandler(log log.Logger, cclient cluster.ReadClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
found, grp, err := cclient.GetManifestGroup(r.Context(), requestLeaseID(r))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

if !found {
http.Error(w, "lease not found", http.StatusNotFound)
return
}

mgrp, _, err := grp.FromCRD()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

writeJSON(log, w, &manifest.Manifest{mgrp})
}
}

func leaseKubeEventsHandler(log log.Logger, cclient cluster.ReadClient) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
upgrader := websocket.Upgrader{
Expand Down
6 changes: 3 additions & 3 deletions pkg/apis/akash.network/v2beta2/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (m *Manifest) Deployment() (ctypes.IDeployment, error) {
return nil, err
}

group, schedulerParams, err := m.Spec.Group.fromCRD()
group, schedulerParams, err := m.Spec.Group.FromCRD()
if err != nil {
return nil, err
}
Expand All @@ -185,8 +185,8 @@ func (m *Manifest) Deployment() (ctypes.IDeployment, error) {
}, nil
}

// toAkash returns akash group details formatted from manifest group
func (m *ManifestGroup) fromCRD() (mani.Group, []*SchedulerParams, error) {
// FromCRD returns akash group details formatted from manifest group
func (m *ManifestGroup) FromCRD() (mani.Group, []*SchedulerParams, error) {
am := mani.Group{
Name: m.Name,
Services: make([]mani.Service, 0, len(m.Services)),
Expand Down

0 comments on commit 1b957e8

Please sign in to comment.