diff --git a/init.go b/init.go index 5a021fe..85b373f 100644 --- a/init.go +++ b/init.go @@ -1,48 +1,17 @@ package main import ( - "crypto/rand" - "encoding/binary" "flag" - "os" "zenhack.net/go/sandstorm/exp/spk" ) -type PkgDefParams struct { - SchemaId uint64 - AppId string -} - -func randU64() uint64 { - // It would probably be fine to use math/rand.Uint64 for this, but - // elsewhere randomly generating a key, and I(zenhack) am generally - // nervous about mixing cryptographc and non-cryptographic rngs in - // nearby code. - var ret uint64 - if err := binary.Read(rand.Reader, binary.LittleEndian, &ret); err != nil { - panic(err) - } - return ret -} - func initCmd() { flag.Parse() - key, err := spk.GenerateKey(nil) - chkfatal("Generating a key", err) - - appId, err := key.AppId() - chkfatal("Getting public key", err) - - params := &PkgDefParams{ - AppId: appId.String(), - SchemaId: randU64() | (1 << 63), - } - - chkfatal("Saving the app key", key.AddToFile(*keyringPath)) - - pkgDefFile, err := os.Create("sandstorm-pkgdef.capnp") - chkfatal("Creating sandstorm-pkgdef.capnp", err) - chkfatal("Outputting sandstorm-pkgdef.capnp", PkgDefTemplate.Execute(pkgDefFile, params)) + pkgdef, err := spk.NewApp() + chkfatal("Generating app info", err) + pkgdef.KeyringPath = *keyringPath + pkgdef.PkgDefPath = "sandstorm-pkgdef.capnp" + chkfatal("Emitting app scaffolding", pkgdef.Emit()) } diff --git a/internal/embed-template.go b/internal/embed-template.go deleted file mode 100644 index 82fcb2b..0000000 --- a/internal/embed-template.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -// Embed the sandstorm-pkgdef.capnp template in the docker-spk executable. - -import ( - "fmt" - "io/ioutil" - "os" - "os/exec" -) - -const OutFile = "template.gen.go" - -func chkfatal(err error) { - if err != nil { - panic(err) - } -} - -func main() { - bytes, err := ioutil.ReadFile("sandstorm-pkgdef.capnp.template") - chkfatal(err) - file, err := os.Create(OutFile) - chkfatal(err) - _, err = fmt.Fprintf(file, - `package main - -// This file was auto-generated by ./internal/embed-template.go. -// DO NOT EDIT. - -import "text/template" - -var PkgDefTemplate = template.Must(template.New("pkgdef").Parse(%q)) -`, bytes) - chkfatal(err) - chkfatal(file.Close()) - chkfatal(exec.Command("gofmt", "-w", OutFile).Run()) -} diff --git a/sandstorm-pkgdef.capnp.template b/sandstorm-pkgdef.capnp.template deleted file mode 100644 index 8c0034b..0000000 --- a/sandstorm-pkgdef.capnp.template +++ /dev/null @@ -1,218 +0,0 @@ -@0x{{ .SchemaId | printf "%016x" }}; - -using Spk = import "/sandstorm/package.capnp"; -# This imports: -# https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp -# Check out that file to see the full, documented package definition format. - -const pkgdef :Spk.PackageDefinition = ( - # The package definition. Note that the spk tool looks specifically for the - # "pkgdef" constant. - - id = "{{ .AppId }}", - # Your app ID is actually its public key. The private key was placed in - # your keyring. All updates must be signed with the same key. - - manifest = ( - # This manifest is included in your app package to tell Sandstorm - # about your app. - - appTitle = (defaultText = "Example App"), - - appVersion = 0, # Increment this for every release. - - appMarketingVersion = (defaultText = "0.0.0"), - # Human-readable representation of appVersion. Should match the way you - # identify versions of your app in documentation and marketing. - - actions = [ - # Define your "new document" handlers here. - ( nounPhrase = (defaultText = "instance"), - command = .myCommand - # The command to run when starting for the first time. (".myCommand" - # is just a constant defined at the bottom of the file.) - ) - ], - - continueCommand = .myCommand, - # This is the command called to start your app back up after it has been - # shut down for inactivity. Here we're using the same command as for - # starting a new instance, but you could use different commands for each - # case. - - metadata = ( - # Data which is not needed specifically to execute the app, but is useful - # for purposes like marketing and display. These fields are documented at - # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#add-required-metadata - # and (in deeper detail) in the sandstorm source code, in the Metadata section of - # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp - icons = ( - # Various icons to represent the app in various contexts. - #appGrid = (svg = embed "path/to/appgrid-128x128.svg"), - #grain = (svg = embed "path/to/grain-24x24.svg"), - #market = (svg = embed "path/to/market-150x150.svg"), - #marketBig = (svg = embed "path/to/market-big-300x300.svg"), - ), - - website = "http://example.com", - # This should be the app's main website url. - - codeUrl = "http://example.com", - # URL of the app's source code repository, e.g. a GitHub URL. - # Required if you specify a license requiring redistributing code, but optional otherwise. - - license = (none = void), - # The license this package is distributed under. See - # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#license - - categories = [], - # A list of categories/genres to which this app belongs, sorted with best fit first. - # See the list of categories at - # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#categories - - author = ( - # Fields relating to the author of this app. - - contactEmail = "youremail@example.com", - # Email address to contact for any issues with this app. This includes end-user support - # requests as well as app store administrator requests, so it is very important that this be a - # valid address with someone paying attention to it. - - #pgpSignature = embed "path/to/pgp-signature", - # PGP signature attesting responsibility for the app ID. This is a binary-format detached - # signature of the following ASCII message (not including the quotes, no newlines, and - # replacing with the standard base-32 text format of the app's ID): - # - # "I am the author of the Sandstorm.io app with the following ID: " - # - # You can create a signature file using `gpg` like so: - # - # echo -n "I am the author of the Sandstorm.io app with the following ID: " | gpg --sign > pgp-signature - # - # Further details including how to set up GPG and how to use keybase.io can be found - # at https://docs.sandstorm.io/en/latest/developing/publishing-apps/#verify-your-identity - - upstreamAuthor = "Example App Team", - # Name of the original primary author of this app, if it is different from the person who - # produced the Sandstorm package. Setting this implies that the author connected to the PGP - # signature only "packaged" the app for Sandstorm, rather than developing the app. - # Remove this line if you consider yourself as the author of the app. - ), - - #pgpKeyring = embed "path/to/pgp-keyring", - # A keyring in GPG keyring format containing all public keys needed to verify PGP signatures in - # this manifest (as of this writing, there is only one: `author.pgpSignature`). - # - # To generate a keyring containing just your public key, do: - # - # gpg --export > keyring - # - # Where `` is a PGP key ID or email address associated with the key. - - #description = (defaultText = embed "path/to/description.md"), - # The app's description in Github-flavored Markdown format, to be displayed e.g. - # in an app store. Note that the Markdown is not permitted to contain HTML nor image tags (but - # you can include a list of screenshots separately). - - shortDescription = (defaultText = "one-to-three words"), - # A very short (one-to-three words) description of what the app does. For example, - # "Document editor", or "Notetaking", or "Email client". This will be displayed under the app - # title in the grid view in the app market. - - screenshots = [ - # Screenshots to use for marketing purposes. Examples below. - # Sizes are given in device-independent pixels, so if you took these - # screenshots on a Retina-style high DPI screen, divide each dimension by two. - - #(width = 746, height = 795, jpeg = embed "path/to/screenshot-1.jpeg"), - #(width = 640, height = 480, png = embed "path/to/screenshot-2.png"), - ], - #changeLog = (defaultText = embed "path/to/sandstorm-specific/changelog.md"), - # Documents the history of changes in Github-flavored markdown format (with the same restrictions - # as govern `description`). We recommend formatting this with an H1 heading for each version - # followed by a bullet list of changes. - ), - ), - - #bridgeConfig = ( - # # Used for integrating permissions and roles into the Sandstorm shell - # # and for sandstorm-http-bridge to pass to your app. - # # Uncomment this block and adjust the permissions and roles to make - # # sense for your app. - # # For more information, see high-level documentation at - # # https://docs.sandstorm.io/en/latest/developing/auth/ - # # and advanced details in the "BridgeConfig" section of - # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp - # viewInfo = ( - # # For details on the viewInfo field, consult "ViewInfo" in - # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp - # - # permissions = [ - # # Permissions which a user may or may not possess. A user's current - # # permissions are passed to the app as a comma-separated list of `name` - # # fields in the X-Sandstorm-Permissions header with each request. - # # - # # IMPORTANT: only ever append to this list! Reordering or removing fields - # # will change behavior and permissions for existing grains! To deprecate a - # # permission, or for more information, see "PermissionDef" in - # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp - # ( - # name = "editor", - # # Name of the permission, used as an identifier for the permission in cases where string - # # names are preferred. Used in sandstorm-http-bridge's X-Sandstorm-Permissions HTTP header. - # - # title = (defaultText = "editor"), - # # Display name of the permission, e.g. to display in a checklist of permissions - # # that may be assigned when sharing. - # - # description = (defaultText = "grants ability to modify data"), - # # Prose describing what this role means, suitable for a tool tip or similar help text. - # ), - # ], - # roles = [ - # # Roles are logical collections of permissions. For instance, your app may have - # # a "viewer" role and an "editor" role - # ( - # title = (defaultText = "editor"), - # # Name of the role. Shown in the Sandstorm UI to indicate which users have which roles. - # - # permissions = [true], - # # An array indicating which permissions this role carries. - # # It should be the same length as the permissions array in - # # viewInfo, and the order of the lists must match. - # - # verbPhrase = (defaultText = "can make changes to the document"), - # # Brief explanatory text to show in the sharing UI indicating - # # what a user assigned this role will be able to do with the grain. - # - # description = (defaultText = "editors may view all site data and change settings."), - # # Prose describing what this role means, suitable for a tool tip or similar help text. - # ), - # ( - # title = (defaultText = "viewer"), - # permissions = [false], - # verbPhrase = (defaultText = "can view the document"), - # description = (defaultText = "viewers may view what other users have written."), - # ), - # ], - # ), - # #apiPath = "/api", - # # Apps can export an API to the world. The API is to be used primarily by Javascript - # # code and native apps, so it can't serve out regular HTML to browsers. If a request - # # comes in to your app's API, sandstorm-http-bridge will prefix the request's path with - # # this string, if specified. - #), -); - -const myCommand :Spk.Manifest.Command = ( - # Here we define the command used to start up your server. - argv = ["/path/to/server"], - environ = [ - # Note that this defines the *entire* environment seen by your app. - (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin"), - (key = "SANDSTORM", value = "1"), - # Export SANDSTORM=1 into the environment, so that apps running within Sandstorm - # can detect if $SANDSTORM="1" at runtime, switching UI and/or backend to use - # the app's Sandstorm-specific integration code. - ] -); diff --git a/template.gen.go b/template.gen.go deleted file mode 100644 index dbccdb0..0000000 --- a/template.gen.go +++ /dev/null @@ -1,8 +0,0 @@ -package main - -// This file was auto-generated by ./internal/embed-template.go. -// DO NOT EDIT. - -import "text/template" - -var PkgDefTemplate = template.Must(template.New("pkgdef").Parse("@0x{{ .SchemaId | printf \"%016x\" }};\n\nusing Spk = import \"/sandstorm/package.capnp\";\n# This imports:\n# https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp\n# Check out that file to see the full, documented package definition format.\n\nconst pkgdef :Spk.PackageDefinition = (\n # The package definition. Note that the spk tool looks specifically for the\n # \"pkgdef\" constant.\n\n id = \"{{ .AppId }}\",\n # Your app ID is actually its public key. The private key was placed in\n # your keyring. All updates must be signed with the same key.\n\n manifest = (\n # This manifest is included in your app package to tell Sandstorm\n # about your app.\n\n appTitle = (defaultText = \"Example App\"),\n\n appVersion = 0, # Increment this for every release.\n\n appMarketingVersion = (defaultText = \"0.0.0\"),\n # Human-readable representation of appVersion. Should match the way you\n # identify versions of your app in documentation and marketing.\n\n actions = [\n # Define your \"new document\" handlers here.\n ( nounPhrase = (defaultText = \"instance\"),\n command = .myCommand\n # The command to run when starting for the first time. (\".myCommand\"\n # is just a constant defined at the bottom of the file.)\n )\n ],\n\n continueCommand = .myCommand,\n # This is the command called to start your app back up after it has been\n # shut down for inactivity. Here we're using the same command as for\n # starting a new instance, but you could use different commands for each\n # case.\n\n metadata = (\n # Data which is not needed specifically to execute the app, but is useful\n # for purposes like marketing and display. These fields are documented at\n # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#add-required-metadata\n # and (in deeper detail) in the sandstorm source code, in the Metadata section of\n # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp\n icons = (\n # Various icons to represent the app in various contexts.\n #appGrid = (svg = embed \"path/to/appgrid-128x128.svg\"),\n #grain = (svg = embed \"path/to/grain-24x24.svg\"),\n #market = (svg = embed \"path/to/market-150x150.svg\"),\n #marketBig = (svg = embed \"path/to/market-big-300x300.svg\"),\n ),\n\n website = \"http://example.com\",\n # This should be the app's main website url.\n\n codeUrl = \"http://example.com\",\n # URL of the app's source code repository, e.g. a GitHub URL.\n # Required if you specify a license requiring redistributing code, but optional otherwise.\n\n license = (none = void),\n # The license this package is distributed under. See\n # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#license\n\n categories = [],\n # A list of categories/genres to which this app belongs, sorted with best fit first.\n # See the list of categories at\n # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#categories\n\n author = (\n # Fields relating to the author of this app.\n\n contactEmail = \"youremail@example.com\",\n # Email address to contact for any issues with this app. This includes end-user support\n # requests as well as app store administrator requests, so it is very important that this be a\n # valid address with someone paying attention to it.\n\n #pgpSignature = embed \"path/to/pgp-signature\",\n # PGP signature attesting responsibility for the app ID. This is a binary-format detached\n # signature of the following ASCII message (not including the quotes, no newlines, and\n # replacing with the standard base-32 text format of the app's ID):\n #\n # \"I am the author of the Sandstorm.io app with the following ID: \"\n #\n # You can create a signature file using `gpg` like so:\n #\n # echo -n \"I am the author of the Sandstorm.io app with the following ID: \" | gpg --sign > pgp-signature\n #\n # Further details including how to set up GPG and how to use keybase.io can be found\n # at https://docs.sandstorm.io/en/latest/developing/publishing-apps/#verify-your-identity\n\n upstreamAuthor = \"Example App Team\",\n # Name of the original primary author of this app, if it is different from the person who\n # produced the Sandstorm package. Setting this implies that the author connected to the PGP\n # signature only \"packaged\" the app for Sandstorm, rather than developing the app.\n # Remove this line if you consider yourself as the author of the app.\n ),\n\n #pgpKeyring = embed \"path/to/pgp-keyring\",\n # A keyring in GPG keyring format containing all public keys needed to verify PGP signatures in\n # this manifest (as of this writing, there is only one: `author.pgpSignature`).\n #\n # To generate a keyring containing just your public key, do:\n #\n # gpg --export > keyring\n #\n # Where `` is a PGP key ID or email address associated with the key.\n\n #description = (defaultText = embed \"path/to/description.md\"),\n # The app's description in Github-flavored Markdown format, to be displayed e.g.\n # in an app store. Note that the Markdown is not permitted to contain HTML nor image tags (but\n # you can include a list of screenshots separately).\n\n shortDescription = (defaultText = \"one-to-three words\"),\n # A very short (one-to-three words) description of what the app does. For example,\n # \"Document editor\", or \"Notetaking\", or \"Email client\". This will be displayed under the app\n # title in the grid view in the app market.\n\n screenshots = [\n # Screenshots to use for marketing purposes. Examples below.\n # Sizes are given in device-independent pixels, so if you took these\n # screenshots on a Retina-style high DPI screen, divide each dimension by two.\n\n #(width = 746, height = 795, jpeg = embed \"path/to/screenshot-1.jpeg\"),\n #(width = 640, height = 480, png = embed \"path/to/screenshot-2.png\"),\n ],\n #changeLog = (defaultText = embed \"path/to/sandstorm-specific/changelog.md\"),\n # Documents the history of changes in Github-flavored markdown format (with the same restrictions\n # as govern `description`). We recommend formatting this with an H1 heading for each version\n # followed by a bullet list of changes.\n ),\n ),\n\n #bridgeConfig = (\n # # Used for integrating permissions and roles into the Sandstorm shell\n # # and for sandstorm-http-bridge to pass to your app.\n # # Uncomment this block and adjust the permissions and roles to make\n # # sense for your app.\n # # For more information, see high-level documentation at\n # # https://docs.sandstorm.io/en/latest/developing/auth/\n # # and advanced details in the \"BridgeConfig\" section of\n # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp\n # viewInfo = (\n # # For details on the viewInfo field, consult \"ViewInfo\" in\n # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp\n #\n # permissions = [\n # # Permissions which a user may or may not possess. A user's current\n # # permissions are passed to the app as a comma-separated list of `name`\n # # fields in the X-Sandstorm-Permissions header with each request.\n # #\n # # IMPORTANT: only ever append to this list! Reordering or removing fields\n # # will change behavior and permissions for existing grains! To deprecate a\n # # permission, or for more information, see \"PermissionDef\" in\n # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp\n # (\n # name = \"editor\",\n # # Name of the permission, used as an identifier for the permission in cases where string\n # # names are preferred. Used in sandstorm-http-bridge's X-Sandstorm-Permissions HTTP header.\n #\n # title = (defaultText = \"editor\"),\n # # Display name of the permission, e.g. to display in a checklist of permissions\n # # that may be assigned when sharing.\n #\n # description = (defaultText = \"grants ability to modify data\"),\n # # Prose describing what this role means, suitable for a tool tip or similar help text.\n # ),\n # ],\n # roles = [\n # # Roles are logical collections of permissions. For instance, your app may have\n # # a \"viewer\" role and an \"editor\" role\n # (\n # title = (defaultText = \"editor\"),\n # # Name of the role. Shown in the Sandstorm UI to indicate which users have which roles.\n #\n # permissions = [true],\n # # An array indicating which permissions this role carries.\n # # It should be the same length as the permissions array in\n # # viewInfo, and the order of the lists must match.\n #\n # verbPhrase = (defaultText = \"can make changes to the document\"),\n # # Brief explanatory text to show in the sharing UI indicating\n # # what a user assigned this role will be able to do with the grain.\n #\n # description = (defaultText = \"editors may view all site data and change settings.\"),\n # # Prose describing what this role means, suitable for a tool tip or similar help text.\n # ),\n # (\n # title = (defaultText = \"viewer\"),\n # permissions = [false],\n # verbPhrase = (defaultText = \"can view the document\"),\n # description = (defaultText = \"viewers may view what other users have written.\"),\n # ),\n # ],\n # ),\n # #apiPath = \"/api\",\n # # Apps can export an API to the world. The API is to be used primarily by Javascript\n # # code and native apps, so it can't serve out regular HTML to browsers. If a request\n # # comes in to your app's API, sandstorm-http-bridge will prefix the request's path with\n # # this string, if specified.\n #),\n);\n\nconst myCommand :Spk.Manifest.Command = (\n # Here we define the command used to start up your server.\n argv = [\"/path/to/server\"],\n environ = [\n # Note that this defines the *entire* environment seen by your app.\n (key = \"PATH\", value = \"/usr/local/bin:/usr/bin:/bin\"),\n (key = \"SANDSTORM\", value = \"1\"),\n # Export SANDSTORM=1 into the environment, so that apps running within Sandstorm\n # can detect if $SANDSTORM=\"1\" at runtime, switching UI and/or backend to use\n # the app's Sandstorm-specific integration code.\n ]\n);\n"))