Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marketplace service new api for manifest #837

Merged
merged 12 commits into from
Mar 29, 2019
5 changes: 2 additions & 3 deletions commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ type ServiceExecutor interface {

// MarketplaceExecutor is an interface that handles marketplace commands.
type MarketplaceExecutor interface {
CreateManifest(path string, hash string) (provider.MarketplaceManifestData, error)
UploadServiceFiles(path string, manifest provider.MarketplaceManifestData) (protocol string, source string, err error)
PublishServiceVersion(sid, manifest, manifestProtocol, from string) (provider.Transaction, error)
UploadSource(path string) (deployment provider.MarketplaceDeployedSource, err error)
PublishServiceVersion(service provider.MarketplaceManifestServiceData, from string) (provider.Transaction, error)
CreateServiceOffer(sid string, price string, duration string, from string) (provider.Transaction, error)
Purchase(sid, offerIndex, from string) ([]provider.Transaction, error)
SendSignedTransaction(signedTransaction string) (provider.TransactionReceipt, error)
Expand Down
74 changes: 35 additions & 39 deletions commands/marketplace_publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ package commands

import (
"fmt"
"strings"

"github.com/mesg-foundation/core/commands/provider"
"github.com/mesg-foundation/core/service/importer"
"github.com/mesg-foundation/core/utils/pretty"
"github.com/mesg-foundation/core/utils/readme"
"github.com/spf13/cobra"
survey "gopkg.in/AlecAivazis/survey.v1"
)

const (
// marketplaceServiceHashVersion is the version of the service hash used by the core.
marketplaceServiceHashVersion = "1"
)

type marketplacePublishCmd struct {
baseMarketplaceCmd

path string
manifest provider.MarketplaceManifestData
service provider.MarketplaceService
path string
sid string
hash string

e Executor
}
Expand All @@ -35,45 +41,22 @@ func newMarketplacePublishCmd(e Executor) *marketplacePublishCmd {
}

func (c *marketplacePublishCmd) preRunE(cmd *cobra.Command, args []string) error {
var (
err error
question = "a new service"
)

if err := c.askAccountAndPassphrase(); err != nil {
return err
}

c.path = getFirstOrCurrentPath(args)

sid, hash, err := deployService(c.e, c.path, map[string]string{})
var err error
c.sid, c.hash, err = deployService(c.e, c.path, map[string]string{})
if err != nil {
return err
}
fmt.Printf("%s Service deployed with sid %s and hash %s\n", pretty.SuccessSign, pretty.Success(sid), pretty.Success(hash))

c.manifest, err = c.e.CreateManifest(c.path, hash)
if err != nil {
return err
}

pretty.Progress("Getting service data...", func() {
c.service, err = c.e.GetService(c.manifest.Service.Definition.Sid)
})
outputError, isMarketplaceError := err.(provider.MarketplaceErrorOutput)
if err != nil && !isMarketplaceError {
return err
}
if outputError.Code != "notFound" {
question = "a new version of service"
if !strings.EqualFold(c.service.Owner, c.account) {
return fmt.Errorf("the service's owner %q is different than the specified account", c.service.Owner)
}
}
fmt.Printf("%s Service deployed with sid %s and hash %s\n", pretty.SuccessSign, pretty.Success(c.sid), pretty.Success(c.hash))

var confirmed bool
if err := survey.AskOne(&survey.Confirm{
Message: fmt.Sprintf("Are you sure to publish %s %q from path %q using account %q?", question, c.manifest.Service.Definition.Sid, c.path, c.account),
Message: fmt.Sprintf("Are you sure to publish a new version of service %q from path %q using account %q?", c.sid, c.path, c.account),
}, &confirmed, nil); err != nil {
return err
}
Expand All @@ -86,21 +69,34 @@ func (c *marketplacePublishCmd) preRunE(cmd *cobra.Command, args []string) error

func (c *marketplacePublishCmd) runE(cmd *cobra.Command, args []string) error {
var (
tx provider.Transaction
err error
manifestProtocol string
manifestSource string
tx provider.Transaction
err error
deployment provider.MarketplaceDeployedSource
)

pretty.Progress("Uploading service source code on the marketplace...", func() {
// TODO: add a progress for the upload
manifestProtocol, manifestSource, err = c.e.UploadServiceFiles(c.path, c.manifest)
deployment, err = c.e.UploadSource(c.path)
})
if err != nil {
return err
}
definition, err := importer.From(c.path)
if err != nil {
return err
}
readme, err := readme.Lookup(c.path)
if err != nil {
return err
}
pretty.Progress("Publishing service on the marketplace...", func() {
tx, err = c.e.PublishServiceVersion(c.manifest.Service.Definition.Sid, manifestSource, manifestProtocol, c.account)
tx, err = c.e.PublishServiceVersion(provider.MarketplaceManifestServiceData{
Definition: *definition,
Hash: c.hash,
HashVersion: marketplaceServiceHashVersion,
Readme: readme,
Deployment: deployment,
}, c.account)
if err != nil {
return
}
Expand All @@ -110,9 +106,9 @@ func (c *marketplacePublishCmd) runE(cmd *cobra.Command, args []string) error {
return err
}
fmt.Printf("%s Service published with success\n", pretty.SuccessSign)
fmt.Printf("%s See it on the marketplace: https://marketplace.mesg.com/services/%s\n", pretty.SuccessSign, c.manifest.Service.Definition.Sid)
fmt.Printf("%s See it on the marketplace: https://marketplace.mesg.com/services/%s\n", pretty.SuccessSign, c.sid)

fmt.Printf("%s To create a service offer, execute the command:\n\tmesg-core marketplace create-offer %s\n", pretty.SuccessSign, c.manifest.Service.Definition.Sid)
fmt.Printf("%s To create a service offer, execute the command:\n\tmesg-core marketplace create-offer %s\n", pretty.SuccessSign, c.sid)
antho1404 marked this conversation as resolved.
Show resolved Hide resolved

return nil
}
102 changes: 16 additions & 86 deletions commands/mocks/Executor.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 10 additions & 41 deletions commands/provider/marketplace_provider.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package provider

import (
"bytes"
"encoding/json"

"github.com/docker/docker/pkg/archive"
"github.com/mesg-foundation/core/ipfs"
"github.com/mesg-foundation/core/protobuf/coreapi"
"github.com/mesg-foundation/core/service/importer"
"github.com/mesg-foundation/core/utils/readme"
)

// MarketplaceProvider is a struct that provides all methods required by service command.
Expand All @@ -22,12 +19,10 @@ func NewMarketplaceProvider(c coreapi.CoreClient) *MarketplaceProvider {
}

// PublishServiceVersion executes the create service version task
func (p *MarketplaceProvider) PublishServiceVersion(sid, manifest, manifestProtocol, from string) (Transaction, error) {
func (p *MarketplaceProvider) PublishServiceVersion(service MarketplaceManifestServiceData, from string) (Transaction, error) {
input := marketplacePublishServiceVersionTaskInputs{
marketplaceTransactionTaskInputs: marketplaceTransactionTaskInputs{From: from},
Sid: sid,
Manifest: manifest,
ManifestProtocol: manifestProtocol,
Service: service,
}
var output Transaction
return output, p.call("publishServiceVersion", input, &output)
Expand Down Expand Up @@ -85,49 +80,23 @@ func (p *MarketplaceProvider) IsAuthorized(sid string, versionHash string, addre
return output.Authorized, output.Sid, output.Source, output.Type, p.call("isAuthorized", input, &output)
}

// UploadServiceFiles upload the tarball and the definition file, and returns the address of the definition file
func (p *MarketplaceProvider) UploadServiceFiles(path string, manifest MarketplaceManifestData) (protocol string, source string, err error) {
// UploadSource upload the tarball, and returns the address of the uploaded sources
func (p *MarketplaceProvider) UploadSource(path string) (MarketplaceDeployedSource, error) {
// upload service source to IPFS
tar, err := archive.TarWithOptions(path, &archive.TarOptions{
Compression: archive.Gzip,
})
if err != nil {
return "", "", err
return MarketplaceDeployedSource{}, err
}
tarballResponse, err := ipfs.Add("tarball", tar)
if err != nil {
return "", "", err
}

manifest.Service.Deployment.Type = marketplaceDeploymentType
manifest.Service.Deployment.Source = tarballResponse.Hash

// upload manifest
manifestData, err := json.Marshal(manifest)
if err != nil {
return "", "", err
}
definitionResponse, err := ipfs.Add("manifest", bytes.NewReader(manifestData))
if err != nil {
return "", "", err
}

return marketplaceDeploymentType, definitionResponse.Hash, nil
}

// CreateManifest creates the manifest file for the service in path.
func (p *MarketplaceProvider) CreateManifest(path string, hash string) (MarketplaceManifestData, error) {
var data MarketplaceManifestData
definition, err := importer.From(path)
if err != nil {
return data, err
return MarketplaceDeployedSource{}, err
}
data.Version = marketplacePublishVersion
data.Service.Hash = hash
data.Service.HashVersion = marketplaceServiceHashVersion
data.Service.Definition = *definition
data.Service.Readme, err = readme.Lookup(path)
return data, err
return MarketplaceDeployedSource{
Type: marketplaceDeploymentType,
Source: tarballResponse.Hash,
}, nil
}

func (p *MarketplaceProvider) call(task string, inputs interface{}, output interface{}) error {
Expand Down
Loading