Documentation
¶
Overview ¶
Package gitmirror builds a local git mirror of this checkout's examples/ directory and serves it over git's real smart-HTTP protocol (see Serve), with GIT_CONFIG_GLOBAL insteadOf rules (see WriteGitConfig) redirecting "github.com/cloudposse/atmos.git//examples/..." fetches to it -- so the acceptance suite never depends on live GitHub connectivity for vendor/import fixtures, while atmos itself remains unaware of the mirror: it authenticates and gets rewritten by git exactly as it would against the real host, running the same token-injection code path a production clone does.
It also carries the "clone a throwaway local git repo instead of the real network" helpers the source-provisioner JIT tests use for non-atmos upstreams (see JITRepo), folded in from the former tests/jit_source_local_repo_test.go so both mechanisms live in one place.
Index ¶
- Constants
- Variables
- func Build(root string) error
- func FileURI(path string) string
- func InitJITSourceRepo(t *testing.T) string
- func RewriteJITSourceURIs(t *testing.T, dir, repoURI string)
- func RunJITSourceGit(t *testing.T, dir string, args ...string)
- func WriteGitConfig(path, serverURL string, tokens []string) error
- type Option
- type Request
- type Server
Constants ¶
const ( Owner = "cloudposse" Repo = "atmos" )
Owner and Repo identify the single upstream this package mirrors today: github.com/cloudposse/atmos.
Variables ¶
var JITSourceRepoFiles = map[string]string{
"exports/context.tf": "variable \"enabled\" {\n type = bool\n default = true\n}\n",
"exports/README.md": "# exports\n",
"exports/examples/complete/main.tf": "# excluded by examples/**\n",
"releases/nginx-ingress/helmfile.yaml": "releases: []\n",
"releases/nginx-ingress/README.md": "# nginx-ingress\n",
"main.pkr.hcl": "source \"null\" \"example\" {\n communicator = \"none\"\n}\n",
"variables.pkrvars.hcl": "ami_name = \"example\"\n",
"README.md": "# stand-in for public sources\n",
}
JITSourceRepoFiles is the content of the local stand-in repository: the `exports/` module the terraform fixtures vendor (only `context.tf` must exist; the README and examples/ exercise excluded_paths), the helmfile release directory, and packer templates at the repository root.
var JITSourceRepoTags = []string{"0.25.0", "0.126.0"}
JITSourceRepoTags are the `version:` values the fixtures pin, all pointing at the single commit; `main` (the packer fixture's version) is the branch.
var JITSourceUpstreams = []string{
"github.com/cloudposse/terraform-null-label",
"github.com/cloudposse-archives/helmfiles",
"github.com/aws-samples/amazon-eks-custom-amis",
}
JITSourceUpstreams lists the public repositories the source-provisioner fixtures point at. The fixtures keep their real-world URIs (they double as documentation); tests rewrite only the repository part of each `uri:` in their sandboxed copy via RewriteJITSourceURIs, so `//subpath` and `version:` keep working exactly as they do against GitHub.
Functions ¶
func Build ¶
Build creates a bare git mirror of this checkout's examples/ directory at <root>/cloudposse/atmos.git, on branch main. Only examples/ is copied (the only subtree any test-case fixture vendors from cloudposse/atmos), so the mirror stays small and fast to build.
Root is resolved to an absolute path before use: the push into the bare mirror below runs with cmd.Dir set to a scratch directory, so a relative root would otherwise be interpreted relative to that scratch directory instead of the caller's intended location.
func FileURI ¶
FileURI converts a filesystem path into a file:// URI usable as a git remote or GIT_CONFIG insteadOf target. On Windows it correctly forms a URI like file:///C:/repo (a volume name needs an extra leading slash after the scheme).
func InitJITSourceRepo ¶
InitJITSourceRepo creates the local git repository the source-provisioner tests clone from instead of GitHub, and returns a `git::file://` URI for it. Cloning over the network made these tests fail whenever a hosted runner's DNS blipped mid-clone -- on a code path (git clone through go-getter) that is identical for a file:// remote, minus the network.
func RewriteJITSourceURIs ¶
RewriteJITSourceURIs points every fixture `uri:` under dir's stack catalog at repoURI, keeping any `//subpath` suffix. It only touches the sandboxed copy a test is about to run against, never the checked-in fixture.
func RunJITSourceGit ¶
RunJITSourceGit runs git in dir and fails the test on error.
func WriteGitConfig ¶
WriteGitConfig writes a git config file at path with insteadOf rules that redirect every github.com/<Owner>/<Repo>.git fetch to serverURL (a Server's URL, see Serve): one rule per token in tokens, spelled out in the userinfo form atmos hands git after CustomGitDetector injects that token, plus one anonymous rule (covering both the https and ssh forms) for callers that never inject a token at all.
A separate rule per token is required because git's insteadOf is a plain string-prefix rewrite, not URL-aware: "https://x-access-token:TOKEN_A@github.com/..." and "https://x-access-token:TOKEN_B@github.com/..." are different strings even though they name the same repository, so each token needs its own rule spelling out that exact prefix.
The file is meant to be installed process-wide via the GIT_CONFIG_GLOBAL environment variable (not GIT_CONFIG_COUNT/KEY_n/VALUE_n): pkg/downloader/custom_git_detector.go's brokerInsteadOfMatchesURL only recognizes a live auth broker's GIT_CONFIG_* env entries, so a GIT_CONFIG_GLOBAL file mirror never trips that check and token injection always runs -- the same code path a production clone takes.
Types ¶
type Option ¶
type Option func(*Server)
Option configures a Server at construction time.
func AllowAnonymous ¶
func AllowAnonymous() Option
AllowAnonymous accepts requests carrying no Authorization header at all, instead of the default 401. Needed for cases that fetch without any token, e.g. the ssh insteadOf form, or a test case that deliberately scrubs all credentials.
type Request ¶
type Request struct {
Method string // HTTP method, e.g. "GET" or "POST".
Path string // URL path, e.g. "/cloudposse/atmos.git/info/refs".
User string // Basic-Auth username the request authenticated as, or "" if anonymous/rejected.
}
Request records one HTTP request the mirror Server handled, for test assertions that a git client actually authenticated (or didn't) the way a scenario expects.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a local git-over-HTTP server backed by git-http-backend -- the same CGI program a real git host runs behind its HTTP frontend -- so a clone against it exercises git's actual smart-HTTP transport instead of a synthetic file:// mirror, and atmos's own credential handling (token injection, GIT_CONFIG insteadOf detection) runs the same code path it would against a real host. It validates a Basic-Auth token against a registry the test controls (see RegisterToken) instead of trusting every request, so a test can assert atmos authenticated (or didn't) exactly the way a real broker-fronted clone would.
Only fetches (git-upload-pack) are served; receive-pack (push) is always rejected -- this mirror only ever needs to answer clones/fetches of the read-only snapshot Build publishes.
func Serve ¶
Serve starts a local HTTP server exposing every bare repository under root (see Build) via git's smart-HTTP protocol, fetches only. Callers register acceptable Basic-Auth tokens with RegisterToken before pointing a git client at Server.URL(); the caller must Close the server when done.
Root is resolved to an absolute path before use: it becomes both cgi.Handler's working directory and the GIT_PROJECT_ROOT git-http-backend resolves request paths against, so a relative root would be interpreted relative to whatever directory the CGI subprocess happens to start in rather than the caller's intended location.
func (*Server) Close ¶
func (s *Server) Close()
Close shuts down the underlying HTTP server. Safe to call once, matching http.Server.Close.
func (*Server) RegisterToken ¶
RegisterToken adds t to the set of Basic-Auth passwords the server accepts. The username half of the credential is never checked -- only the token matters, matching how a real token-based git host authenticates (the username is a convention, e.g. GitHub's "x-access-token", not a secret).
func (*Server) Requests ¶
Requests returns a snapshot of every request the server has handled so far, for assertions like "the clone authenticated as x-access-token".
func (*Server) URL ¶
URL returns the server's base URL (e.g. "http://127.0.0.1:54321"), with no trailing slash.