diff --git a/.drone/drone.cue b/.drone/drone.cue new file mode 100644 index 0000000..c90f066 --- /dev/null +++ b/.drone/drone.cue @@ -0,0 +1,108 @@ +package drone + +let pipeline = { + kind: "pipeline" + platform: {os: "linux", arch: "amd64"} +} + +let build_image = "jdbgrafana/haproxy-mixin-build-image:0.0.2" + +let step = { + check_artifacts: { + name: "check artifacts" + image: build_image + commands: [ + "make build", + "git diff --exit-code", + ] + } +} + +pipelines: [ + pipeline & { + name: "pr" + steps: [ + { + name: "check .drone/drone.yml" + image: build_image + commands: [ + "make .drone/drone.yml", + "git diff --exit-code -- .drone/drone.yml", + ] + }, + { + name: "check formatting" + image: build_image + commands: [ + "make fmt", + "git diff --exit-code", + ] + }, + step.check_artifacts, + { + name: "lint mixin" + image: build_image + commands: [ + "make lint", + ] + }, + ] + trigger: event: include: ["pull_request"] + }, + pipeline & { + name: "default" + steps: [ + { + name: "fmt" + image: build_image + commands: [ + "make fmt", + ] + }, + { + name: ".drone/drone.yml" + image: build_image + commands: [ + "make .drone/drone.yml", + ] + }, + { + name: "build" + image: build_image + commands: [ + "make build", + ] + }, + { + name: "lint" + image: build_image + commands: [ + "make lint", + ] + }, + ] + trigger: event: include: ["custom"] + }, + pipeline & { + name: "release" + steps: [ + step.check_artifacts, + { + name: "make dist/haproxy-mixin.tar.gz" + image: build_image + commands: [ + "make dist/haproxy-mixin.tar.gz", + ] + }, + { + name: "publish" + image: "plugins/github-release" + settings: { + api_key: from_secret: "github_token" + files: "dist/*" + } + }, + ] + trigger: event: include: ["tag"] + }, +] diff --git a/.drone/drone.yml b/.drone/drone.yml new file mode 100644 index 0000000..704e575 --- /dev/null +++ b/.drone/drone.yml @@ -0,0 +1,83 @@ +name: pr +kind: pipeline +platform: + os: linux + arch: amd64 +steps: +- name: check .drone/drone.yml + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make .drone/drone.yml + - git diff --exit-code -- .drone/drone.yml +- name: check formatting + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make fmt + - git diff --exit-code +- name: check artifacts + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make build + - git diff --exit-code +- name: lint mixin + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make lint +trigger: + event: + include: + - pull_request +--- +name: default +kind: pipeline +platform: + os: linux + arch: amd64 +steps: +- name: fmt + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make fmt +- name: .drone/drone.yml + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make .drone/drone.yml +- name: build + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make build +- name: lint + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make lint +trigger: + event: + include: + - custom +--- +name: release +kind: pipeline +platform: + os: linux + arch: amd64 +steps: +- name: check artifacts + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make build + - git diff --exit-code +- name: make dist/haproxy-mixin.tar.gz + image: jdbgrafana/haproxy-mixin-build-image:0.0.2 + commands: + - make dist/haproxy-mixin.tar.gz +- name: publish + image: plugins/github-release + settings: + files: dist/* + api_key: + from_secret: github_token +trigger: + event: + include: + - tag + diff --git a/.drone/dump_tool.cue b/.drone/dump_tool.cue new file mode 100644 index 0000000..830c1d6 --- /dev/null +++ b/.drone/dump_tool.cue @@ -0,0 +1,12 @@ +package drone + +import ( + "encoding/yaml" + "tool/cli" +) + +command: dump: { + task: print: cli.Print & { + text: yaml.MarshalStream(pipelines) + } +} diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..581650d --- /dev/null +++ b/.envrc @@ -0,0 +1,5 @@ +if command -v lorri >/dev/null; then + eval "$(lorri direnv)" +fi + +export PROMETHEUS_PORT=9091 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..895ffc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/result +/dist/haproxy-mixin.tar.gz diff --git a/Makefile b/Makefile index 038c959..96a71d2 100644 --- a/Makefile +++ b/Makefile @@ -52,3 +52,27 @@ post: dashboards/$(DASHBOARD) -H "Authorization: Bearer $${GRAFANA_API_TOKEN}" \ -d "$$(jq '{ "dashboard": ., "overwrite": true }' dashboards/$(DASHBOARD))" \ $(GRAFANA_URL)/api/dashboards/db + +.drone/drone.yml: ## Write out YAML drone configuration +.drone/drone.yml: .drone/drone.cue .drone/dump_tool.cue $(wildcard cue.mod/**/github.com/drone/drone-yaml/yaml/*.cue) + cue fmt $< + cue vet -c $< + cue cmd dump ./.drone/ > $@ + drone lint $@ + +.PHONY: haproxy-mixin-build-image +haproxy-mixin-build-image: ## Build the haproxy-mixin-build-image +haproxy-mixin-build-image: build-image.nix common.nix $(wildcard nix/*nix) + docker load --input $$(nix-build build-image.nix) + +.PHONY: inspect-build-image +inspect-build-image: ## Inspect the haproxy-mixin-build-image +inspect-build-image: + docker save jdbgrafana/haproxy-mixin-build-image | tar x --to-stdout --wildcards '*/layer.tar' | tar tv | sort -nr -k3 + +dist: + mkdir -p dist + +dist/haproxy-mixin.tar.gz: ## Create a release of the haproxy-mixin artifacts +dist/haproxy-mixin.tar.gz: $(wildcard dashboards/*.json) $(wildcard alerts/*yaml) $(wildcard rules/*.yaml) $(wildcard img/*.png) | dist + tar -c -f $@ $^ diff --git a/build-image.nix b/build-image.nix new file mode 100644 index 0000000..dee8d90 --- /dev/null +++ b/build-image.nix @@ -0,0 +1,10 @@ +let + common = import ./common.nix; + sources = import ./nix/sources.nix; + pkgs = import sources.nixpkgs { }; +in pkgs.dockerTools.buildImage { + name = "jdbgrafana/haproxy-mixin-build-image"; + created = "now"; + tag = "0.0.1"; + contents = common.buildTools; +} diff --git a/common.nix b/common.nix new file mode 100644 index 0000000..b6dd310 --- /dev/null +++ b/common.nix @@ -0,0 +1,29 @@ +let + sources = import ./nix/sources.nix; + pkgs = import sources.nixpkgs { + overlays = [ + (self: super: + let inherit (super) callPackage; + in { + jsonnet-bundler = callPackage ./nix/jsonnet-bundler.nix { }; + mixtool = callPackage ./nix/mixtool.nix { }; + }) + ]; + }; +in { + # devTools are packages specifically for development environments. + devTools = [ pkgs.docker pkgs.docker-compose ]; + # buildTools are packages needed for dev and CI builds. + buildTools = [ + pkgs.bash + pkgs.coreutils + pkgs.cue + pkgs.drone-cli + pkgs.git + pkgs.gnumake + pkgs.gnutar + pkgs.jsonnet + pkgs.jsonnet-bundler + pkgs.mixtool + ]; +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/build_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/build_go_gen.cue new file mode 100644 index 0000000..f2d9b79 --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/build_go_gen.cue @@ -0,0 +1,14 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Build: { + args?: {[string]: string} @go(Args,map[string]string) + cache_from?: [...string] @go(CacheFrom,[]string) + context?: string @go(Context) + dockerfile?: string @go(Dockerfile) + image?: string @go(Image) + labels?: {[string]: string} @go(Labels,map[string]string) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/cond_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/cond_go_gen.cue new file mode 100644 index 0000000..efb3435 --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/cond_go_gen.cue @@ -0,0 +1,26 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +// Conditions defines a group of conditions. +#Conditions: { + action?: #Condition @go(Action) + cron?: #Condition @go(Cron) + ref?: #Condition @go(Ref) + repo?: #Condition @go(Repo) + instance?: #Condition @go(Instance) + target?: #Condition @go(Target) + event?: #Condition @go(Event) + branch?: #Condition @go(Branch) + status?: #Condition @go(Status) + paths?: #Condition @go(Paths) + matrix?: {[string]: string} @go(Matrix,map[string]string) +} + +// Condition defines a runtime condition. +#Condition: { + include?: [...string] @go(Include,[]string) + exclude?: [...string] @go(Exclude,[]string) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/cron_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/cron_go_gen.cue new file mode 100644 index 0000000..221e613 --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/cron_go_gen.cue @@ -0,0 +1,23 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Cron: { + version?: string @go(Version) + kind?: string @go(Kind) + type?: string @go(Type) + name?: string @go(Name) + spec?: #CronSpec @go(Spec) +} + +#CronSpec: { + schedule?: string @go(Schedule) + branch?: string @go(Branch) + deployment?: #CronDeployment @go(Deploy) +} + +#CronDeployment: { + target?: string @go(Target) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/env_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/env_go_gen.cue new file mode 100644 index 0000000..898cf8b --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/env_go_gen.cue @@ -0,0 +1,10 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Variable: { + value?: string @go(Value) + from_secret?: string @go(Secret) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/manifest_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/manifest_go_gen.cue new file mode 100644 index 0000000..07e3376 --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/manifest_go_gen.cue @@ -0,0 +1,23 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#KindCron: "cron" +#KindPipeline: "pipeline" +#KindRegistry: "registry" +#KindSecret: "secret" +#KindSignature: "signature" + +#Manifest: { + Resources: [...#Resource] @go(,[]Resource) +} + +#Resource: _ + +#RawResource: { + Version: string + Kind: string + Type: string +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/param_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/param_go_gen.cue new file mode 100644 index 0000000..3a13f75 --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/param_go_gen.cue @@ -0,0 +1,10 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Parameter: { + value?: _ @go(Value,interface{}) + from_secret?: string @go(Secret) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/pipeline_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/pipeline_go_gen.cue new file mode 100644 index 0000000..3294fcd --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/pipeline_go_gen.cue @@ -0,0 +1,116 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +// Pipeline is a resource that defines a continuous +// delivery pipeline. +#Pipeline: { + version?: string @go(Version) + kind?: string @go(Kind) + type?: string @go(Type) + name?: string @go(Name) + clone?: #Clone @go(Clone) + concurrency?: #Concurrency @go(Concurrency) + depends_on?: [...string] @go(DependsOn,[]string) + node?: {[string]: string} @go(Node,map[string]string) + platform?: #Platform @go(Platform) + image_pull_secrets?: [...string] @go(PullSecrets,[]string) + services?: [...null | #Container] @go(Services,[]*Container) + steps?: [...null | #Container] @go(Steps,[]*Container) + trigger?: #Conditions @go(Trigger) + volumes?: [...null | #Volume] @go(Volumes,[]*Volume) + workspace?: #Workspace @go(Workspace) +} + +#Clone: { + disable?: bool @go(Disable) + depth?: int @go(Depth) + skip_verify?: bool @go(SkipVerify) +} + +#Concurrency: { + limit?: int @go(Limit) +} + +#Container: { + build?: null | #Build @go(Build,*Build) + command?: [...string] @go(Command,[]string) + commands?: [...string] @go(Commands,[]string) + detach?: bool @go(Detach) + depends_on?: [...string] @go(DependsOn,[]string) + devices?: [...null | #VolumeDevice] @go(Devices,[]*VolumeDevice) + dns?: [...string] @go(DNS,[]string) + dns_search?: [...string] @go(DNSSearch,[]string) + entrypoint?: [...string] @go(Entrypoint,[]string) + environment?: {[string]: null | #Variable} @go(Environment,map[string]*Variable) + extra_hosts?: [...string] @go(ExtraHosts,[]string) + failure?: string @go(Failure) + image?: string @go(Image) + network_mode?: string @go(Network) + name?: string @go(Name) + ports?: [...null | #Port] @go(Ports,[]*Port) + privileged?: bool @go(Privileged) + pull?: string @go(Pull) + push?: null | #Push @go(Push,*Push) + resources?: null | #Resources @go(Resources,*Resources) + settings?: {[string]: null | #Parameter} @go(Settings,map[string]*Parameter) + shell?: string @go(Shell) + user?: string @go(User) + volumes?: [...null | #VolumeMount] @go(Volumes,[]*VolumeMount) + when?: #Conditions @go(When) + working_dir?: string @go(WorkingDir) +} + +#Resources: { + // Limits describes the maximum amount of compute + // resources allowed. + limits?: null | #ResourceObject @go(Limits,*ResourceObject) + + // Requests describes the minimum amount of + // compute resources required. + requests?: null | #ResourceObject @go(Requests,*ResourceObject) +} + +#ResourceObject: { + cpu: float64 @go(CPU) + memory: #BytesSize @go(Memory) +} + +#Platform: { + os?: string @go(OS) + arch?: string @go(Arch) + variant?: string @go(Variant) + version?: string @go(Version) +} + +#Volume: { + name?: string @go(Name) + temp?: null | #VolumeEmptyDir @go(EmptyDir,*VolumeEmptyDir) + host?: null | #VolumeHostPath @go(HostPath,*VolumeHostPath) +} + +#VolumeDevice: { + name?: string @go(Name) + path?: string @go(DevicePath) +} + +#VolumeMount: { + name?: string @go(Name) + path?: string @go(MountPath) +} + +#VolumeEmptyDir: { + medium?: string @go(Medium) + size_limit?: #BytesSize @go(SizeLimit) +} + +#VolumeHostPath: { + path?: string @go(Path) +} + +#Workspace: { + base?: string @go(Base) + path?: string @go(Path) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/port_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/port_go_gen.cue new file mode 100644 index 0000000..cb8e05b --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/port_go_gen.cue @@ -0,0 +1,11 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Port: { + port?: int @go(Port) + host?: int @go(Host) + protocol?: string @go(Protocol) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/push_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/push_go_gen.cue new file mode 100644 index 0000000..c19da3d --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/push_go_gen.cue @@ -0,0 +1,9 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Push: { + image?: string @go(Image) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/registry_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/registry_go_gen.cue new file mode 100644 index 0000000..5f381fc --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/registry_go_gen.cue @@ -0,0 +1,12 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Registry: { + version: string @go(Version) + kind?: string @go(Kind) + type?: string @go(Type) + data?: {[string]: string} @go(Data,map[string]string) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/secret_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/secret_go_gen.cue new file mode 100644 index 0000000..20dbcc3 --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/secret_go_gen.cue @@ -0,0 +1,25 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Secret: { + version?: string @go(Version) + kind?: string @go(Kind) + type?: string @go(Type) + name?: string @go(Name) + data?: string @go(Data) + get?: #SecretGet @go(Get) +} + +#SecretGet: { + path?: string @go(Path) + name?: string @go(Name) + key?: string @go(Key) +} + +#ExternalData: { + path?: string @go(Path) + name?: string @go(Name) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/signature_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/signature_go_gen.cue new file mode 100644 index 0000000..6356004 --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/signature_go_gen.cue @@ -0,0 +1,11 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +#Signature: { + version?: string @go(Version) + kind: string @go(Kind) + hmac: string @go(Hmac) +} diff --git a/cue.mod/gen/github.com/drone/drone-yaml/yaml/unit_go_gen.cue b/cue.mod/gen/github.com/drone/drone-yaml/yaml/unit_go_gen.cue new file mode 100644 index 0000000..5cf80ca --- /dev/null +++ b/cue.mod/gen/github.com/drone/drone-yaml/yaml/unit_go_gen.cue @@ -0,0 +1,10 @@ +// Code generated by cue get go. DO NOT EDIT. + +//cue:generate cue get go github.com/drone/drone-yaml/yaml + +package yaml + +// BytesSize stores a human-readable size in bytes, +// kibibytes, mebibytes, gibibytes, or tebibytes +// (eg. "44kiB", "17MiB"). +#BytesSize: int64 diff --git a/cue.mod/usr/github.com/drone/drone-yaml/yaml/container.cue b/cue.mod/usr/github.com/drone/drone-yaml/yaml/container.cue new file mode 100644 index 0000000..7141e62 --- /dev/null +++ b/cue.mod/usr/github.com/drone/drone-yaml/yaml/container.cue @@ -0,0 +1,6 @@ +package yaml + +#Container: { + name: string + image: string +} diff --git a/cue.mod/usr/github.com/drone/drone-yaml/yaml/pipeline.cue b/cue.mod/usr/github.com/drone/drone-yaml/yaml/pipeline.cue new file mode 100644 index 0000000..964575e --- /dev/null +++ b/cue.mod/usr/github.com/drone/drone-yaml/yaml/pipeline.cue @@ -0,0 +1,6 @@ +package yaml + +#Pipeline: { + kind: "pipeline" + name: string +} diff --git a/img/haproxy-backend.png b/img/haproxy-backend.png new file mode 100644 index 0000000..0f48daa Binary files /dev/null and b/img/haproxy-backend.png differ diff --git a/img/haproxy-frontend.png b/img/haproxy-frontend.png new file mode 100644 index 0000000..2dcb990 Binary files /dev/null and b/img/haproxy-frontend.png differ diff --git a/img/haproxy-overview.png b/img/haproxy-overview.png new file mode 100644 index 0000000..f52e9f5 Binary files /dev/null and b/img/haproxy-overview.png differ diff --git a/img/haproxy-server.png b/img/haproxy-server.png new file mode 100644 index 0000000..35aff77 Binary files /dev/null and b/img/haproxy-server.png differ diff --git a/nix/jsonnet-bundler.nix b/nix/jsonnet-bundler.nix new file mode 100644 index 0000000..19874e2 --- /dev/null +++ b/nix/jsonnet-bundler.nix @@ -0,0 +1,21 @@ +{ stdenv, buildGoModule, fetchFromGitHub }: + +buildGoModule rec { + pname = "jsonnet-bundler"; + version = "0.4.0"; + + src = fetchFromGitHub { + owner = pname; + repo = pname; + rev = "v${version}"; + sha256 = "0pk6nf8r0wy7lnsnzyjd3vgq4b2kb3zl0xxn01ahpaqgmwpzajlk"; + }; + + subPackages = [ "cmd/jb" ]; + vendorSha256 = null; + + meta = with stdenv.lib; { + description = "A Jsonnet package manager"; + license = licenses.asl20; + }; +} diff --git a/nix/mixtool.nix b/nix/mixtool.nix new file mode 100644 index 0000000..909ddc2 --- /dev/null +++ b/nix/mixtool.nix @@ -0,0 +1,21 @@ +{ stdenv, buildGoModule, fetchFromGitHub }: + +buildGoModule rec { + pname = "mixtool"; + version = "bd0efc3"; + + src = fetchFromGitHub { + owner = "monitoring-mixins"; + repo = pname; + rev = "${version}"; + sha256 = "1kh2axna553q7lrmgak8l7jlnmbdfkfci240bqa3040pd82j3q1c"; + }; + + subPackages = [ "cmd/mixtool" ]; + vendorSha256 = "10wvckrwrc7xs3dng9m6lznsaways2wycxnl9h8jynp4h2cw22ml"; + + meta = with stdenv.lib; { + description = "Helper for easily working with Jsonnet mixins"; + license = licenses.asl20; + }; +} diff --git a/nix/sources.json b/nix/sources.json new file mode 100644 index 0000000..87d2104 --- /dev/null +++ b/nix/sources.json @@ -0,0 +1,26 @@ +{ + "niv": { + "branch": "master", + "description": "Easy dependency management for Nix projects", + "homepage": "https://github.com/nmattia/niv", + "owner": "nmattia", + "repo": "niv", + "rev": "ba57d5a29b4e0f2085917010380ef3ddc3cf380f", + "sha256": "1kpsvc53x821cmjg1khvp1nz7906gczq8mp83664cr15h94sh8i4", + "type": "tarball", + "url": "https://github.com/nmattia/niv/archive/ba57d5a29b4e0f2085917010380ef3ddc3cf380f.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "nixpkgs": { + "branch": "nixos-20.09", + "description": "Nix Packages collection", + "homepage": "", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "29e9c10750e2b35a0e47db55f36c685ef9219f4e", + "sha256": "0bbqmip233mqvk2q46pbhjw3djr68p9m120kl37kw2758a5kggay", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/29e9c10750e2b35a0e47db55f36c685ef9219f4e.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + } +} diff --git a/nix/sources.nix b/nix/sources.nix new file mode 100644 index 0000000..b64b8f8 --- /dev/null +++ b/nix/sources.nix @@ -0,0 +1,148 @@ +# This file has been generated by Niv. + +let + + # + # The fetchers. fetch_ fetches specs of type . + # + + fetch_file = pkgs: spec: + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; } + else + pkgs.fetchurl { inherit (spec) url sha256; }; + + fetch_tarball = pkgs: name: spec: + let + ok = str: ! builtins.isNull (builtins.match "[a-zA-Z0-9+-._?=]" str); + # sanitize the name, though nix will still fail if name starts with period + name' = stringAsChars (x: if ! ok x then "-" else x) "${name}-src"; + in + if spec.builtin or true then + builtins_fetchTarball { name = name'; inherit (spec) url sha256; } + else + pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; + + fetch_git = spec: + builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; + + fetch_local = spec: spec.path; + + fetch_builtin-tarball = name: throw + ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=tarball -a builtin=true''; + + fetch_builtin-url = name: throw + ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=file -a builtin=true''; + + # + # Various helpers + # + + # The set of packages used when specs are fetched using non-builtins. + mkPkgs = sources: + let + sourcesNixpkgs = + import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {}; + hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; + hasThisAsNixpkgsPath = == ./.; + in + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import {} + else + abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; + + # The actual fetching function. + fetch = pkgs: name: spec: + + if ! builtins.hasAttr "type" spec then + abort "ERROR: niv spec ${name} does not have a 'type' attribute" + else if spec.type == "file" then fetch_file pkgs spec + else if spec.type == "tarball" then fetch_tarball pkgs name spec + else if spec.type == "git" then fetch_git spec + else if spec.type == "local" then fetch_local spec + else if spec.type == "builtin-tarball" then fetch_builtin-tarball name + else if spec.type == "builtin-url" then fetch_builtin-url name + else + abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + + # If the environment variable NIV_OVERRIDE_${name} is set, then use + # the path directly as opposed to the fetched source. + replace = name: drv: + let + saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; + ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; + in + if ersatz == "" then drv else ersatz; + + # Ports of functions for older nix versions + + # a Nix version of mapAttrs if the built-in doesn't exist + mapAttrs = builtins.mapAttrs or ( + f: set: with builtins; + listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) + ); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 + range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 + stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 + stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); + concatStrings = builtins.concatStringsSep ""; + + # fetchTarball version that is compatible between all the versions of Nix + builtins_fetchTarball = { url, name, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchTarball; + in + if lessThan nixVersion "1.12" then + fetchTarball { inherit name url; } + else + fetchTarball attrs; + + # fetchurl version that is compatible between all the versions of Nix + builtins_fetchurl = { url, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchurl; + in + if lessThan nixVersion "1.12" then + fetchurl { inherit url; } + else + fetchurl attrs; + + # Create the final "sources" from the config + mkSources = config: + mapAttrs ( + name: spec: + if builtins.hasAttr "outPath" spec + then abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = replace name (fetch config.pkgs name spec); } + ) config.sources; + + # The "config" used by the fetchers + mkConfig = + { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null + , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) + , pkgs ? mkPkgs sources + }: rec { + # The sources, i.e. the attribute set of spec name to spec + inherit sources; + + # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers + inherit pkgs; + }; + +in +mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..73d148c --- /dev/null +++ b/shell.nix @@ -0,0 +1,3 @@ +{ pkgs ? import { } }: +let common = import ./common.nix; +in pkgs.mkShell { buildInputs = common.buildTools ++ common.devTools; }