{"id":28578188,"url":"https://github.com/digitalocean/go-nbd","last_synced_at":"2025-08-22T03:11:46.945Z","repository":{"id":256480060,"uuid":"846707054","full_name":"digitalocean/go-nbd","owner":"digitalocean","description":"NBD client implementation in Go, free of any CGO or system-specific dependencies","archived":false,"fork":false,"pushed_at":"2025-07-14T16:08:14.000Z","size":41,"stargazers_count":6,"open_issues_count":0,"forks_count":3,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-08-09T01:49:02.626Z","etag":null,"topics":["nbd","nbd-client","network-block-device","protocol"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digitalocean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-08-23T19:27:31.000Z","updated_at":"2025-05-06T23:11:34.000Z","dependencies_parsed_at":"2025-02-14T21:27:44.760Z","dependency_job_id":"3d7261af-c704-4ce3-8f46-8c267bbe48d4","html_url":"https://github.com/digitalocean/go-nbd","commit_stats":null,"previous_names":["digitalocean/go-nbd"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/digitalocean/go-nbd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-nbd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-nbd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-nbd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-nbd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalocean","download_url":"https://codeload.github.com/digitalocean/go-nbd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-nbd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271578516,"owners_count":24784051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-22T02:00:08.480Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nbd","nbd-client","network-block-device","protocol"],"created_at":"2025-06-11T01:09:07.132Z","updated_at":"2025-08-22T03:11:46.903Z","avatar_url":"https://github.com/digitalocean.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cp align=center\u003ego-nbd\u003c/p\u003e\n\n\u003cp align=center\u003e\nNBD client implementation in Go, free of any CGO or system-specific\ndependencies.\n\u003c/p\u003e\n\n\u003chr /\u003e\n\n\u003cp align=center\u003e:warning:\u003c/p\u003e\n\ngo-nbd implements enough of the NBD protocol specification[^1] to be useful\nin some general circumstances, but it is not an exhaustive and complete\nimplementation (yet.) For example, it does not initiate a hard disconnect\nfrom the server in all instances where the specification states the client\nMUST initiate a hard disconnect.\n\nFor more information, see [unimplemented](#unimplemented).\n\n\u003chr /\u003e\n\n## Goals\n\n* Implement enough of the client-side of the Network Block Device protocol\n  to be generally useful.\n* No dependencies on CGO, header files, or other platform-specific things.\n\n## Unimplemented\n\nIf you have a use-case for any of these things, please file an issue.\n\n* Old-style option negotation is specifically not supported.\n* `NBD_OPT_PEEK_EXPORT` - The protocol spec describes this as withdrawn and not\nin use.\n* `NBD_CMD_RESIZE` - The protocol spec describes this as defined by an experimental\n`RESIZE` extension.\n* `EXTENDED_HEADER` extension - the initial release of this module is targeting only\nthe base Network Block Device protocol.\n* `RESIZE` extension - the initial release of this module is targeting only\nthe base Network Block Device protocol.\n\n## Security\n\nPlease see [SECURITY.md](https://github.com/digitalocean/go-nbd/security/policy) for\ninformation on reporting security-related concerns to DigitalOcean's security team.\n\nThank you!\n\n## Tutorial\n\nFirst, you'll want to dial an NBD server to construct an nbd.Conn:\n\n```go\nuri := nbd.MustURI(os.Getenv(\"EXAMPLE_NBD_URI\"))\nvar dialer nbd.Dialer\nconn, err := dialer.Dial(context.TODO(), uri)\nif err != nil {\n    return fmt.Errorf(\"nbd dial: %w\", err)\n}\ndefer conn.Close()\n```\n\nAt which point, you'll want to complete the NBD handshake before\nnegotiating options:\n\n```go\nerr = conn.Connect()\nif err != nil {\n    return fmt.Errorf(\"nbd connect: %w\", err)\n}\ndefer conn.Abort()\n```\n\nIf the call to Connect is successful, your nbd.Conn is now in the\noption negotiation phase. In this phase, you can call the following\nmethods on your nbd.Conn:\n\n```go\nfunc (c *Conn) Abort() error\nfunc (c *Conn) Close() error\nfunc (c *Conn) ExportName(name string) (size uint64, flags TransmissionFlags, err error)\nfunc (c *Conn) Go(name string, requests []InfoRequest) (ExportInfo, error)\nfunc (c *Conn) Info(name string, requests []InfoRequest) (ExportInfo, error)\nfunc (c *Conn) List() (exports []string, err error)\nfunc (c *Conn) ListMetaContext(export string, queries ...string) ([]MetaContext, error)\nfunc (c *Conn) SetMetaContext(export string, query string, additional ...string) ([]MetaContext, error)\nfunc (c *Conn) StartTLS(config *tls.Config) error\nfunc (c *Conn) StructuredReplies() error\n```\n\nNote that successful execution of the following methods will transition\nthe nbd.Conn into the transmission phase:\n\n```go\nfunc (c *Conn) ExportName(name string) (size uint64, flags TransmissionFlags, err error)\nfunc (c *Conn) Go(name string, requests []InfoRequest) (ExportInfo, error)\n```\n\n\u003cp align=center\u003e:warning: Don't forget to \u003ccode\u003edefer conn.Disconnect()\u003c/code\u003e after entering the\ntransmission phase! :warning:\u003c/p\u003e\n\nOnce in the transmission phase, you can call the following methods on the\nnbd.Conn:\n\n```go\nfunc (c *Conn) Abort() error\nfunc (c *Conn) BlockStatus(flags CommandFlags, offset uint64, length uint32) (BlockStatus, error)\nfunc (c *Conn) Cache(flags CommandFlags, offset uint64, length uint32) error\nfunc (c *Conn) Close() error\nfunc (c *Conn) Disconnect() error\nfunc (c *Conn) Flush(flags CommandFlags) error\nfunc (c *Conn) Read(flags CommandFlags, offset uint64, length uint32) ([]Read, error)\nfunc (c *Conn) Trim(flags CommandFlags, offset uint64, length uint32) error\nfunc (c *Conn) Write(flags CommandFlags, offset uint64, data []byte) error\nfunc (c *Conn) WriteZeroes(flags CommandFlags, offset uint64, length uint32) error\n```\n\n## FAQ\n\n\u003e Is it safe to interact with the Conn object from multiple goroutines?\n\nPrefer instead to see if the server supports multiple connections by seeing if\nit sets the TransmissionFlagCanMultiConn bit in its transmission flags. If it\ndoes, use nbd.Dialer to create additional Conns and negotiate the same options as\nbefore.\n\nYou can get a copy of the transmission flags by calling Conn.Info (a read-only\noperation that does not transition the connection into transmission phase),\nor by calling one of: Conn.Go, Conn.ExportName.\n\nNote that the NBD protocol spec requires clients to perform the option negotation\nphase synchronously. This module does not have any guardrails against client code\nviolating this constraint by invoking option negotiation methods on an nbd.Conn\nfrom multiple goroutines.\n\n\u003e What is the difference between Conn.Abort, Conn.Disconnect, and Conn.Close?\n\n* Conn.Close closes the underlying transport.\n* Conn.Abort politely terminates the option phase with the server. It is\n  a no-op if the connection has transitioned to the transmission phase.\n* Conn.Disconnect politely terminates the transmission phase with the server.\n\nThese are intended to work conveniently with client code defer statements\nto tear down the connection in the reverse order that it was brought up.\n\nFor example (error handling omitted for brevity):\n\n```go\nuri := nbd.MustURI(os.Getenv(\"EXAMPLE_NBD_URI\"))\n\n// nbd.Dialer opens the underlying transport (TCP, UNIX),\n// so conn.Close will close the transport connection.\nvar dialer nbd.Dialer\nconn, _ := dialer.Dial(context.TODO(), uri)\ndefer conn.Close()\n\n// conn.Connect performs the NBD handshake and begins\n// the option phase, so conn.Abort will politely terminate\n// this phase with the server (or no-op if the Conn has\n// transitioned into the transmission phase.)\n_ = conn.Connect()\ndefer conn.Abort()\n\n// conn.Go or conn.ExportName transition the Conn into the\n// transmission phase, so conn.Disconnect will politely\n// terminate this phase with the server.\n_, _ = conn.Go(\"vda\", nbd.InfoRequestAll())\ndefer conn.Disconnect()\n```\n\n[^1]: https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fgo-nbd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalocean%2Fgo-nbd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fgo-nbd/lists"}