{"id":37789400,"url":"https://github.com/spectrocloud/peg","last_synced_at":"2026-01-16T15:15:29.963Z","repository":{"id":61624535,"uuid":"538914523","full_name":"spectrocloud/peg","owner":"spectrocloud","description":null,"archived":false,"fork":false,"pushed_at":"2025-12-02T09:03:25.000Z","size":136,"stargazers_count":1,"open_issues_count":2,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-12-05T04:56:15.232Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/spectrocloud.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-09-20T09:46:16.000Z","updated_at":"2025-12-02T09:03:26.000Z","dependencies_parsed_at":"2023-10-02T17:15:08.314Z","dependency_job_id":null,"html_url":"https://github.com/spectrocloud/peg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/spectrocloud/peg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spectrocloud%2Fpeg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spectrocloud%2Fpeg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spectrocloud%2Fpeg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spectrocloud%2Fpeg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spectrocloud","download_url":"https://codeload.github.com/spectrocloud/peg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spectrocloud%2Fpeg/sbom","scorecard":{"id":840910,"data":{"date":"2025-08-11","repo":{"name":"github.com/spectrocloud/peg","commit":"c5da7125e30fcfb4a1e792692299a9c9907f0ded"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Code-Review","score":7,"reason":"Found 9/12 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/lint.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/spectrocloud/peg/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/spectrocloud/peg/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/spectrocloud/peg/release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/spectrocloud/peg/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/spectrocloud/peg/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/spectrocloud/peg/test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/spectrocloud/peg/test.yml/master?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":5,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'master'","Info: 'force pushes' disabled on branch 'master'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'master'","Info: 'stale review dismissal' is required to merge on branch 'master'","Warn: required approving review count is 1 on branch 'master'","Warn: codeowners review is not required on branch 'master'","Warn: 'last push approval' is disabled on branch 'master'","Warn: no status checks found to merge onto branch 'master'","Info: PRs are required in order to make changes on branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"11 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2023-2402 / GHSA-45x7-px36-x8w8","Warn: Project is vulnerable to: GO-2024-3321 / GHSA-v778-237x-gjrc","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2023-1571 / GHSA-vvpx-j8f3-3w6h","Warn: Project is vulnerable to: GO-2023-1988 / GHSA-2wrh-6pvc-2jm9","Warn: Project is vulnerable to: GO-2023-2102 / GHSA-4374-p667-p6c8","Warn: Project is vulnerable to: GHSA-qppj-fm5r-hxr3","Warn: Project is vulnerable to: GO-2024-2687 / GHSA-4v7x-pqxf-cx7m","Warn: Project is vulnerable to: GO-2024-3333","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T20:27:31.844Z","repository_id":61624535,"created_at":"2025-08-23T20:27:31.844Z","updated_at":"2025-08-23T20:27:31.844Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-01-16T15:15:28.433Z","updated_at":"2026-01-16T15:15:29.947Z","avatar_url":"https://github.com/spectrocloud.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# peg\n\nPeg my machine!\n\nPeg ease out testing systems on VMs, docker and kubernetes. It is loosely based on the [ginkgo](https://github.com/onsi/ginkgo/) framework, and indeed offers a helper to be used with it.\n\nIt is intended to run either on Github actions, in a docker container or as a companion library for ginkgo/gomega BDD golang test based suites. So it either focuses on trying to run and be plugged in existing workflows - indeed its design is cut rather on pluggability than performance.\n\n## Motivation\n\nIn the Open Source team at SpectroCloud we run our e2e test suites over Github. As we do intensive testing of OS images, we needed a solid foundation to collect common patterns. \nAs we already use ginkgo as testing framework - and that seems to scale as well for testing VMs and systems, here we are with peg. A set of libraries and CLI that help into testing VMs, docker images and Kubernetes cluster. We couldn't find anything out there that simplifies creation of test systems, specifically focused at CIs environment and that could run on top of containers.\n\n## Supported engines\n\n- QEMU (no KVM)\n- Docker\n- Virtualbox\n\nThey share the same common apis, so you can control machine created with the engines in the same way from a testing perspective.\n\nDesign notes: QEMU has no KVM support to allow running QEMU machines inside docker containers. peg doesn't try to be smart by downloading all the required dependencies, instead it uses the smallest possible user-set from such, and tries to abstract from that to guarantee compatibilities between versions. \nSoftware like QEMU, Docker, and Virtualbox needs to be installed in the machine.\n\nIf you are running tests on Github, keep in mind that the Virtualbox engine is specifically tailored for it - you should just be good to go as is with no additional configuration.\n\n## Usage\n\n`peg` both support it's own syntax with yaml files, or either can be just used as a helper library to use with [ginkgo](https://github.com/onsi/ginkgo/).\n\n### CLI\n\nTo run a peg spec, give the spec as argument to peg, or alternative with stdin:\n\n```bash\n$ cat \u003cfile.yaml\u003e | peg -\n$ peg \u003cfile.yaml\u003e\n```\n\nYou can override parts of the specs via CLI, for example, to override the iso from the spec you can:\n```\n$ peg --iso path_to_iso_file \u003cfile.yaml\u003e\n```\n\nExample\n```yaml\nmachine:\n engine: \"qemu\"\n iso: \"https://github.com/c3os-io/c3os/releases/download/v0.57.0/c3os-alpine-v0.57.0.iso\"\n ssh:\n   user: \"c3os\"\n   pass: \"c3os\"\n\nspecs:\n- label: \"download\"\n  describe: \"bar\"\n  assertions:\n   \"Download\":\n    - preOps:\n      - eventuallyConnects: 10\n      command: |  \n        echo aaa\n      expect:\n        containString: \"aaa\"\n```\n\n### As a library for tests\n\n`peg` main use case is to use aside with `ginkgo` tests, however, it can also be used as a standard library to manage and control systems.\n\n```go\nimport (\n    . \"github.com/onsi/ginkgo/v2\"\n    . \"github.com/onsi/gomega\"\n    . \"github.com/spectrocloud/peg/matcher\"\n    machine \"github.com/spectrocloud/peg/pkg/machine\"\n)\n\nDescribe(\"Checking machine integrity\", Label(\"integrity\"), func() {\n    // This could go as well in Before Suite\n    BeforeEach(func() {\n        m, err:= = machine.New(...)\n        Expect(err).ToNot(HaveOccurred())\n        Machine = m\n        err := Machine.Create()\n\t\tExpect(err).ToNot(HaveOccurred())\n    })\n\n    // This could go also as AfterSuite\n    AfterEach(func() {\n        Machine.Stop()\n\t\tMachine.Clean()\n    })\n\n    When(\"the machine boots\", func() {\n        BeforeEach(func() {\n           EventuallyConnects(120)\n        })\n\n        Context(\"and can run sudo commands\", func() {\n            It(\"returns the user name\", func() {\n                result, err:= Sudo(\"id\")\n \t\t        Expect(err).ToNot(HaveOccurred())\n                Expect(result).To(ContainSubstring(\"root\"))\n            })\n        })\n    })\n})\n```\n\nThe machine can be controlled via the interface:\n\n```golang\n\ntype Machine interface {\n\tConfig() MachineConfig\n\tCreate() error\n\tStop() error\n\tClean() error\n\tCreateDisk(diskname, size string) error\n\tCommand(cmd string) (string, error)\n\tReceiveFile(src, dst string) error\n\tSendFile(src, dst, permissions string) error\n}\n\n```\n\n## License\n\nCopyright (c) 2022 Spectro Cloud\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspectrocloud%2Fpeg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspectrocloud%2Fpeg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspectrocloud%2Fpeg/lists"}