Merge ~troyanov/maas:maas-agent into maas:master

Proposed by Anton Troyanov
Status: Merged
Approved by: Anton Troyanov
Approved revision: 6dc8c92a062398930dcd4e1584d5b156af562cde
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~troyanov/maas:maas-agent
Merge into: maas:master
Diff against target: 851 lines (+725/-4)
14 files modified
.golangci.yaml (+188/-0)
Makefile (+18/-4)
src/maasagent/.gitignore (+24/-0)
src/maasagent/Makefile (+49/-0)
src/maasagent/cmd/README.md (+5/-0)
src/maasagent/cmd/agent/README.md (+3/-0)
src/maasagent/cmd/agent/main.go (+5/-0)
src/maasagent/cmd/netmon/README.md (+3/-0)
src/maasagent/cmd/netmon/main.go (+9/-0)
src/maasagent/go.mod (+3/-0)
src/maasagent/go.sum (+0/-0)
src/maasagent/internal/README.md (+3/-0)
src/maasagent/internal/netmon/service.go (+3/-0)
utilities/get_golangci-lint (+412/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Christian Grabowski Approve
Review via email: mp+441357@code.launchpad.net

Commit message

feat: add maas agent project bootstrap

To post a comment you must log in.
Revision history for this message
Christian Grabowski (cgrabowski) wrote :

+1

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b maas-agent lp:~troyanov/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/2341/consoleText
COMMIT: 38722609fb730c0dda0597318838add63191742c

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b maas-agent lp:~troyanov/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/2345/consoleText
COMMIT: 698de23028f5dda899dd31d48583af71ee76b98d

review: Needs Fixing
Revision history for this message
Anton Troyanov (troyanov) wrote :

jenkins: !test

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b maas-agent lp:~troyanov/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 698de23028f5dda899dd31d48583af71ee76b98d

review: Approve
~troyanov/maas:maas-agent updated
6dc8c92... by Anton Troyanov

fixup! ci: change makefile targets related to go lint

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b maas-agent lp:~troyanov/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 6dc8c92a062398930dcd4e1584d5b156af562cde

review: Approve
~troyanov/maas:maas-agent updated
0e5cd53... by Anton Troyanov

fixup! fixup! ci: change makefile targets related to go lint

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.golangci.yaml b/.golangci.yaml
2new file mode 100644
3index 0000000..6855546
4--- /dev/null
5+++ b/.golangci.yaml
6@@ -0,0 +1,188 @@
7+# This file contains all available configuration options
8+# https://golangci-lint.run/usage/linters/
9+
10+run:
11+ timeout: 5m
12+ issues-exit-code: 1
13+ tests: true
14+ # Enables skipping of directories:
15+ # - vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
16+ skip-dirs-use-default: true
17+
18+ # Which files to skip: they will be analyzed, but issues from them won't be reported.
19+ # Default value is empty list,
20+ # but there is no need to include all autogenerated files,
21+ # we confidently recognize autogenerated files.
22+ # If it's not please let us know.
23+ # "/" will be replaced by current OS file path separator to properly work on Windows.
24+ skip-files:
25+ - ".*\\.my\\.go$"
26+ - lib/bad.go
27+
28+ # If set we pass it to "go list -mod={option}". From "go help modules":
29+ # If invoked with -mod=readonly, the go command is disallowed from the implicit
30+ # automatic updating of go.mod described above. Instead, it fails when any changes
31+ # to go.mod are needed. This setting is most useful to check that go.mod does
32+ # not need updates, such as in a continuous integration and testing system.
33+ # If invoked with -mod=vendor, the go command assumes that the vendor
34+ # directory holds the correct copies of dependencies and ignores
35+ # the dependency descriptions in go.mod.
36+ #
37+ # Allowed values: readonly|vendor|mod
38+ # By default, it isn't set.
39+ modules-download-mode: readonly
40+
41+ # Allow multiple parallel golangci-lint instances running.
42+ # If false (default) - golangci-lint acquires file lock on start.
43+ allow-parallel-runners: false
44+
45+
46+# output configuration options
47+output:
48+ # Format: colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions|teamcity
49+ #
50+ # Multiple can be specified by separating them by comma, output can be provided
51+ # for each of them by separating format name and path by colon symbol.
52+ # Output path can be either `stdout`, `stderr` or path to the file to write to.
53+ # Example: "checkstyle:report.xml,json:stdout,colored-line-number"
54+ #
55+ # Default: colored-line-number
56+ format: colored-line-number
57+
58+ # Print lines of code with issue.
59+ # Default: true
60+ print-issued-lines: true
61+
62+ # Print linter name in the end of issue text.
63+ # Default: true
64+ print-linter-name: true
65+
66+ # Make issues output unique by line.
67+ # Default: true
68+ uniq-by-line: true
69+
70+ # Add a prefix to the output file references.
71+ # Default is no prefix.
72+ path-prefix: ""
73+
74+ # Sort results by: filepath, line and column.
75+ sort-results: false
76+
77+
78+linters:
79+ disable-all: true
80+ enable:
81+ - dupl
82+ - errcheck
83+ - exportloopref
84+ - gocritic
85+ - godot
86+ - gofmt
87+ - goimports
88+ - gosec
89+ - gosimple
90+ - govet
91+ # - loggercheck
92+ - nilerr
93+ - nilnil
94+ - noctx
95+ - nolintlint
96+ - nonamedreturns
97+ - revive
98+ - staticcheck
99+ - tagliatelle
100+ - unused
101+ - whitespace
102+ - wsl
103+
104+linters-settings:
105+
106+
107+issues:
108+ # List of regexps of issue texts to exclude.
109+ #
110+ # But independently of this option we use default exclude patterns,
111+ # it can be disabled by `exclude-use-default: false`.
112+ # To list all excluded by default patterns execute `golangci-lint run --help`
113+ #
114+ # Default: https://golangci-lint.run/usage/false-positives/#default-exclusions
115+ exclude: []
116+
117+ # Excluding configuration per-path, per-linter, per-text and per-source
118+ exclude-rules:
119+ # Exclude some linters from running on tests files.
120+ - path: _test\.go
121+ linters:
122+ - gocyclo
123+ - errcheck
124+ - dupl
125+ - gosec
126+
127+ # Exclude known linters from partially hard-vendored code,
128+ # which is impossible to exclude via `nolint` comments.
129+ # `/` will be replaced by current OS file path separator to properly work on Windows.
130+
131+ # Exclude `lll` issues for long lines with `go:generate`.
132+ - linters:
133+ - lll
134+ source: "^//go:generate "
135+
136+ # Independently of option `exclude` we use default exclude patterns,
137+ # it can be disabled by this option.
138+ # To list all excluded by default patterns execute `golangci-lint run --help`.
139+ # Default: true.
140+ exclude-use-default: false
141+
142+ # If set to true exclude and exclude-rules regular expressions become case-sensitive.
143+ # Default: false
144+ exclude-case-sensitive: false
145+
146+ max-same-issues: 0
147+
148+ # Show only new issues: if there are unstaged changes or untracked files,
149+ # only those changes are analyzed, else only changes in HEAD~ are analyzed.
150+ # It's a super-useful option for integration of golangci-lint into existing large codebase.
151+ # It's not practical to fix all existing issues at the moment of integration:
152+ # much better don't allow issues in new code.
153+ #
154+ # Default: false.
155+ new: false
156+
157+ # Show only new issues created after git revision `REV`.
158+ new-from-rev: HEAD
159+
160+ # Show only new issues created in git patch with set file path.
161+ # new-from-patch: path/to/patch/file
162+
163+ # Fix found issues (if it's supported by the linter).
164+ fix: true
165+
166+
167+severity:
168+ # Set the default severity for issues.
169+ #
170+ # If severity rules are defined and the issues do not match or no severity is provided to the rule
171+ # this will be the default severity applied.
172+ # Severities should match the supported severity names of the selected out format.
173+ # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
174+ # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel
175+ # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
176+ # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance
177+ #
178+ # Default value is an empty string.
179+ default-severity: error
180+
181+ # If set to true `severity-rules` regular expressions become case-sensitive.
182+ # Default: false
183+ case-sensitive: true
184+
185+ # When a list of severity rules are provided, severity information will be added to lint issues.
186+ # Severity rules have the same filtering capability as exclude rules
187+ # except you are allowed to specify one matcher per severity rule.
188+ # Only affects out formats that support setting severity information.
189+ #
190+ # Default: []
191+ rules:
192+ - linters:
193+ - dupl
194+ severity: info
195diff --git a/Makefile b/Makefile
196index 73144fe..33f4257 100644
197--- a/Makefile
198+++ b/Makefile
199@@ -1,6 +1,7 @@
200 python := python3
201 snapcraft := SNAPCRAFT_BUILD_INFO=1 snapcraft -v
202
203+BIN_DIR := bin
204 VENV := .ve
205
206 # PPA used by MAAS dependencies. It can be overridden by the env.
207@@ -11,6 +12,8 @@ ifeq ($(MAAS_PPA),)
208 MAAS_PPA = ppa:maas-committers/latest-deps
209 endif
210
211+export PATH := $(PWD)/$(BIN_DIR):$(PATH)
212+
213 # pkg_resources makes some incredible noise about version numbers. They
214 # are not indications of bugs in MAAS so we silence them everywhere.
215 export PYTHONWARNINGS = \
216@@ -128,9 +131,10 @@ swagger-css: $(swagger-dist)
217
218 go-bins:
219 $(MAKE) -j -C src/host-info build
220+ $(MAKE) -j -C src/maasagent build
221 .PHONY: go-bins
222
223-test: test-missing-migrations test-py lint-oapi
224+test: test-missing-migrations test-py lint-oapi test-go
225 .PHONY: test
226
227 test-missing-migrations: bin/database bin/maas-region
228@@ -141,6 +145,10 @@ test-py: bin/test.parallel bin/subunit-1to2 bin/subunit2junitxml bin/subunit2pyu
229 @utilities/run-py-tests-ci
230 .PHONY: test-py
231
232+test-go:
233+ @find src/ -type f -name go.mod -maxdepth 3 -execdir make test \;
234+.PHONY: test-go
235+
236 test-perf: bin/pytest
237 GIT_BRANCH=$(shell git rev-parse --abbrev-ref HEAD) \
238 GIT_HASH=$(shell git rev-parse HEAD) \
239@@ -182,9 +190,9 @@ lint-oapi: openapi.yaml
240
241 # Go fmt
242 lint-go:
243- @find src/ \( -name pkg -o -name vendor \) -prune -o -name '*.go' -exec gofmt -l {} + | \
244- tee /tmp/gofmt.lint
245- @test ! -s /tmp/gofmt.lint
246+ @find src -type f -name go.mod -maxdepth 3 -execdir golangci-lint run -v ./... \; | \
247+ tee /tmp/golangci-lint.lint
248+ @test ! -s /tmp/golangci-lint.lint
249 .PHONY: lint-go
250
251 lint-shell:
252@@ -424,3 +432,9 @@ snap-tree-sync: $(UI_BUILD) go-bins $(SNAP_UNPACKED_DIR_MARKER)
253 src/host-info/bin/ \
254 $(SNAP_UNPACKED_DIR)/usr/share/maas/machine-resources/
255 .PHONY: snap-tree-sync
256+
257+$(BIN_DIR)/golangci-lint: GOLANGCI_VERSION=1.51.2
258+$(BIN_DIR)/golangci-lint: utilities/get_golangci-lint | $(BIN_DIR)
259+ GOBIN="$(realpath $(dir $@))"
260+ sh utilities/get_golangci-lint.sh "v${GOLANGCI_VERSION}"
261+ touch $@
262diff --git a/src/maasagent/.gitignore b/src/maasagent/.gitignore
263new file mode 100644
264index 0000000..c2b1d37
265--- /dev/null
266+++ b/src/maasagent/.gitignore
267@@ -0,0 +1,24 @@
268+### Go ###
269+go.work
270+
271+# Binaries for programs and plugins
272+*.exe
273+*.exe~
274+*.dll
275+*.so
276+*.dylib
277+
278+# Test binary, built with `go test -c`
279+*.test
280+
281+# Output of the go coverage tool
282+*.out
283+
284+# Dependency directories
285+vendor/
286+
287+# BINDIR used for various tools
288+bin/
289+
290+# DISTDIR
291+dist/
292diff --git a/src/maasagent/Makefile b/src/maasagent/Makefile
293new file mode 100644
294index 0000000..c56d4e4
295--- /dev/null
296+++ b/src/maasagent/Makefile
297@@ -0,0 +1,49 @@
298+SHELL := /bin/bash
299+
300+BIN_DIR := bin
301+BUILD_DIR := build
302+
303+GO := go # override to use alternative Go binary
304+VENDOR_DIR := vendor
305+
306+LDFLAGS := -ldflags '-s -w -extldflags "-static"'
307+
308+# Explicitly set cache dirs to avoid situations where we can't mkdir under $HOME (e.g. Launchpad builds)
309+export GOCACHE := $(shell [ -d $(HOME)/.cache ] && echo $(HOME)/.cache/go-cache || mktemp --tmpdir -d tmp.go-cacheXXX)
310+export GOMODCACHE := $(shell [ -d $(HOME)/go ] && echo $(HOME)/go/pkg/mod || mktemp --tmpdir -d tmp.go-mod-cacheXXX)
311+export GOFLAGS := -mod=vendor
312+
313+default: build test lint
314+
315+$(BIN_DIR): ; mkdir -p $@
316+
317+ARTIFACTS := $(subst /,,$(subst cmd/,,$(wildcard cmd/*/)))
318+build: vendor $(addprefix $(BUILD_DIR)/,$(ARTIFACTS))
319+
320+$(BUILD_DIR)/%:
321+ CGO_ENABLED=0 $(GO) build -o $(BUILD_DIR)/$* $(LDFLAGS) cmd/$*/*.go
322+
323+.PHONY: test
324+test:
325+ CGO_ENABLED=1 $(GO) test -race ./...
326+
327+.PHONY: generate
328+generate: $(BIN_DIR)/mockgen
329+ $(GO) generate ./...
330+
331+.PHONY: tools
332+tools: $(BIN_DIR)/mockgen
333+
334+.PHONY: vendor
335+vendor: $(VENDOR_DIR)/modules.txt
336+
337+$(VENDOR_DIR)/modules.txt: go.mod
338+ $(GO) mod vendor
339+
340+$(BIN_DIR)/mockgen: MOCKGEN_VERSION=1.6.0
341+$(BIN_DIR)/mockgen: | $(BIN_DIR)
342+ GOFLAGS="" GOBIN="$(realpath $(dir $@))" $(GO) install github.com/golang/mock/mockgen@v$(MOCKGEN_VERSION)
343+
344+.PHONY: clean
345+clean:
346+ rm -rf $(VENDOR_DIR) $(BIN_DIR) $(BUILD_DIR)
347diff --git a/src/maasagent/cmd/README.md b/src/maasagent/cmd/README.md
348new file mode 100644
349index 0000000..8ddd037
350--- /dev/null
351+++ b/src/maasagent/cmd/README.md
352@@ -0,0 +1,5 @@
353+# `/cmd`
354+
355+The directory name for each application should match the name of the executable you want to have (e.g., /cmd/myapp).
356+
357+It's common to have a small `main` function that imports and invokes the code from the `/internal` and `/pkg` directories and nothing else.
358diff --git a/src/maasagent/cmd/agent/README.md b/src/maasagent/cmd/agent/README.md
359new file mode 100644
360index 0000000..afd1b6a
361--- /dev/null
362+++ b/src/maasagent/cmd/agent/README.md
363@@ -0,0 +1,3 @@
364+# agent
365+
366+MAAS Agent.
367diff --git a/src/maasagent/cmd/agent/main.go b/src/maasagent/cmd/agent/main.go
368new file mode 100644
369index 0000000..7905807
370--- /dev/null
371+++ b/src/maasagent/cmd/agent/main.go
372@@ -0,0 +1,5 @@
373+package main
374+
375+func main() {
376+
377+}
378diff --git a/src/maasagent/cmd/netmon/README.md b/src/maasagent/cmd/netmon/README.md
379new file mode 100644
380index 0000000..efd6623
381--- /dev/null
382+++ b/src/maasagent/cmd/netmon/README.md
383@@ -0,0 +1,3 @@
384+# netmon
385+
386+MAAS Agent Network monitor that can be used as a standalone binary.
387diff --git a/src/maasagent/cmd/netmon/main.go b/src/maasagent/cmd/netmon/main.go
388new file mode 100644
389index 0000000..e83655f
390--- /dev/null
391+++ b/src/maasagent/cmd/netmon/main.go
392@@ -0,0 +1,9 @@
393+package main
394+
395+import (
396+ "launchpad.net/maas/maas/src/maasagent/internal/netmon"
397+)
398+
399+func main() {
400+ netmon.NewService()
401+}
402diff --git a/src/maasagent/go.mod b/src/maasagent/go.mod
403new file mode 100644
404index 0000000..9bee24c
405--- /dev/null
406+++ b/src/maasagent/go.mod
407@@ -0,0 +1,3 @@
408+module launchpad.net/maas/maas/src/maasagent
409+
410+go 1.18
411diff --git a/src/maasagent/go.sum b/src/maasagent/go.sum
412new file mode 100644
413index 0000000..e69de29
414--- /dev/null
415+++ b/src/maasagent/go.sum
416diff --git a/src/maasagent/internal/README.md b/src/maasagent/internal/README.md
417new file mode 100644
418index 0000000..3332284
419--- /dev/null
420+++ b/src/maasagent/internal/README.md
421@@ -0,0 +1,3 @@
422+# `/internal`
423+
424+Private application and library code. This is the code you don't want others importing in their applications or libraries. Note that this layout pattern is enforced by the Go compiler itself.
425diff --git a/src/maasagent/internal/netmon/service.go b/src/maasagent/internal/netmon/service.go
426new file mode 100644
427index 0000000..14ebdc6
428--- /dev/null
429+++ b/src/maasagent/internal/netmon/service.go
430@@ -0,0 +1,3 @@
431+package netmon
432+
433+func NewService() {}
434diff --git a/utilities/get_golangci-lint b/utilities/get_golangci-lint
435new file mode 100644
436index 0000000..291c47a
437--- /dev/null
438+++ b/utilities/get_golangci-lint
439@@ -0,0 +1,412 @@
440+#!/bin/sh
441+set -e
442+
443+usage() {
444+ this=$1
445+ cat <<EOF
446+$this: download go binaries for golangci/golangci-lint
447+
448+Usage: $this [-b] bindir [-d] [tag]
449+ -b sets bindir or installation directory, Defaults to ./bin
450+ -d turns on debug logging
451+ [tag] is a tag from
452+ https://github.com/golangci/golangci-lint/releases
453+ If tag is missing, then the latest will be used.
454+
455+ Generated by godownloader
456+ https://github.com/goreleaser/godownloader
457+
458+EOF
459+ exit 2
460+}
461+
462+parse_args() {
463+ #BINDIR is ./bin unless set be ENV
464+ # over-ridden by flag below
465+
466+ BINDIR=${BINDIR:-./bin}
467+ while getopts "b:dh?x" arg; do
468+ case "$arg" in
469+ b) BINDIR="$OPTARG" ;;
470+ d) log_set_priority 10 ;;
471+ h | \?) usage "$0" ;;
472+ x) set -x ;;
473+ esac
474+ done
475+ shift $((OPTIND - 1))
476+ TAG=$1
477+}
478+# this function wraps all the destructive operations
479+# if a curl|bash cuts off the end of the script due to
480+# network, either nothing will happen or will syntax error
481+# out preventing half-done work
482+execute() {
483+ tmpdir=$(mktemp -d)
484+ log_debug "downloading files into ${tmpdir}"
485+ http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
486+ http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
487+ hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
488+ srcdir="${tmpdir}/${NAME}"
489+ rm -rf "${srcdir}"
490+ (cd "${tmpdir}" && untar "${TARBALL}")
491+ test ! -d "${BINDIR}" && install -d "${BINDIR}"
492+ for binexe in $BINARIES; do
493+ if [ "$OS" = "windows" ]; then
494+ binexe="${binexe}.exe"
495+ fi
496+ install "${srcdir}/${binexe}" "${BINDIR}/"
497+ log_info "installed ${BINDIR}/${binexe}"
498+ done
499+ rm -rf "${tmpdir}"
500+}
501+get_binaries() {
502+ case "$PLATFORM" in
503+ darwin/amd64) BINARIES="golangci-lint" ;;
504+ darwin/arm64) BINARIES="golangci-lint" ;;
505+ darwin/armv6) BINARIES="golangci-lint" ;;
506+ darwin/armv7) BINARIES="golangci-lint" ;;
507+ darwin/mips64) BINARIES="golangci-lint" ;;
508+ darwin/mips64le) BINARIES="golangci-lint" ;;
509+ darwin/ppc64le) BINARIES="golangci-lint" ;;
510+ darwin/s390x) BINARIES="golangci-lint" ;;
511+ freebsd/386) BINARIES="golangci-lint" ;;
512+ freebsd/amd64) BINARIES="golangci-lint" ;;
513+ freebsd/armv6) BINARIES="golangci-lint" ;;
514+ freebsd/armv7) BINARIES="golangci-lint" ;;
515+ freebsd/mips64) BINARIES="golangci-lint" ;;
516+ freebsd/mips64le) BINARIES="golangci-lint" ;;
517+ freebsd/ppc64le) BINARIES="golangci-lint" ;;
518+ freebsd/s390x) BINARIES="golangci-lint" ;;
519+ linux/386) BINARIES="golangci-lint" ;;
520+ linux/amd64) BINARIES="golangci-lint" ;;
521+ linux/arm64) BINARIES="golangci-lint" ;;
522+ linux/armv6) BINARIES="golangci-lint" ;;
523+ linux/armv7) BINARIES="golangci-lint" ;;
524+ linux/mips64) BINARIES="golangci-lint" ;;
525+ linux/mips64le) BINARIES="golangci-lint" ;;
526+ linux/ppc64le) BINARIES="golangci-lint" ;;
527+ linux/s390x) BINARIES="golangci-lint" ;;
528+ linux/riscv64) BINARIES="golangci-lint" ;;
529+ netbsd/386) BINARIES="golangci-lint" ;;
530+ netbsd/amd64) BINARIES="golangci-lint" ;;
531+ netbsd/armv6) BINARIES="golangci-lint" ;;
532+ netbsd/armv7) BINARIES="golangci-lint" ;;
533+ windows/386) BINARIES="golangci-lint" ;;
534+ windows/amd64) BINARIES="golangci-lint" ;;
535+ windows/arm64) BINARIES="golangci-lint" ;;
536+ windows/armv6) BINARIES="golangci-lint" ;;
537+ windows/armv7) BINARIES="golangci-lint" ;;
538+ windows/mips64) BINARIES="golangci-lint" ;;
539+ windows/mips64le) BINARIES="golangci-lint" ;;
540+ windows/ppc64le) BINARIES="golangci-lint" ;;
541+ windows/s390x) BINARIES="golangci-lint" ;;
542+ *)
543+ log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
544+ exit 1
545+ ;;
546+ esac
547+}
548+tag_to_version() {
549+ if [ -z "${TAG}" ]; then
550+ log_info "checking GitHub for latest tag"
551+ else
552+ log_info "checking GitHub for tag '${TAG}'"
553+ fi
554+ REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
555+ if test -z "$REALTAG"; then
556+ log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
557+ exit 1
558+ fi
559+ # if version starts with 'v', remove it
560+ TAG="$REALTAG"
561+ VERSION=${TAG#v}
562+}
563+adjust_format() {
564+ # change format (tar.gz or zip) based on OS
565+ case ${OS} in
566+ windows) FORMAT=zip ;;
567+ esac
568+ true
569+}
570+adjust_os() {
571+ # adjust archive name based on OS
572+ true
573+}
574+adjust_arch() {
575+ # adjust archive name based on ARCH
576+ true
577+}
578+
579+cat /dev/null <<EOF
580+------------------------------------------------------------------------
581+https://github.com/client9/shlib - portable posix shell functions
582+Public domain - http://unlicense.org
583+https://github.com/client9/shlib/blob/master/LICENSE.md
584+but credit (and pull requests) appreciated.
585+------------------------------------------------------------------------
586+EOF
587+is_command() {
588+ command -v "$1" >/dev/null
589+}
590+echoerr() {
591+ echo "$@" 1>&2
592+}
593+log_prefix() {
594+ echo "$0"
595+}
596+_logp=6
597+log_set_priority() {
598+ _logp="$1"
599+}
600+log_priority() {
601+ if test -z "$1"; then
602+ echo "$_logp"
603+ return
604+ fi
605+ [ "$1" -le "$_logp" ]
606+}
607+log_tag() {
608+ case $1 in
609+ 0) echo "emerg" ;;
610+ 1) echo "alert" ;;
611+ 2) echo "crit" ;;
612+ 3) echo "err" ;;
613+ 4) echo "warning" ;;
614+ 5) echo "notice" ;;
615+ 6) echo "info" ;;
616+ 7) echo "debug" ;;
617+ *) echo "$1" ;;
618+ esac
619+}
620+log_debug() {
621+ log_priority 7 || return 0
622+ echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
623+}
624+log_info() {
625+ log_priority 6 || return 0
626+ echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
627+}
628+log_err() {
629+ log_priority 3 || return 0
630+ echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
631+}
632+log_crit() {
633+ log_priority 2 || return 0
634+ echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
635+}
636+uname_os() {
637+ os=$(uname -s | tr '[:upper:]' '[:lower:]')
638+ case "$os" in
639+ msys*) os="windows" ;;
640+ mingw*) os="windows" ;;
641+ cygwin*) os="windows" ;;
642+ win*) os="windows" ;;
643+ esac
644+ echo "$os"
645+}
646+uname_arch() {
647+ arch=$(uname -m)
648+ case $arch in
649+ x86_64) arch="amd64" ;;
650+ x86) arch="386" ;;
651+ i686) arch="386" ;;
652+ i386) arch="386" ;;
653+ aarch64) arch="arm64" ;;
654+ armv5*) arch="armv5" ;;
655+ armv6*) arch="armv6" ;;
656+ armv7*) arch="armv7" ;;
657+ esac
658+ echo ${arch}
659+}
660+uname_os_check() {
661+ os=$(uname_os)
662+ case "$os" in
663+ darwin) return 0 ;;
664+ dragonfly) return 0 ;;
665+ freebsd) return 0 ;;
666+ linux) return 0 ;;
667+ android) return 0 ;;
668+ nacl) return 0 ;;
669+ netbsd) return 0 ;;
670+ openbsd) return 0 ;;
671+ plan9) return 0 ;;
672+ solaris) return 0 ;;
673+ windows) return 0 ;;
674+ esac
675+ log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value."
676+ return 1
677+}
678+uname_arch_check() {
679+ arch=$(uname_arch)
680+ case "$arch" in
681+ 386) return 0 ;;
682+ amd64) return 0 ;;
683+ arm64) return 0 ;;
684+ armv5) return 0 ;;
685+ armv6) return 0 ;;
686+ armv7) return 0 ;;
687+ ppc64) return 0 ;;
688+ ppc64le) return 0 ;;
689+ mips) return 0 ;;
690+ mipsle) return 0 ;;
691+ mips64) return 0 ;;
692+ mips64le) return 0 ;;
693+ s390x) return 0 ;;
694+ riscv64) return 0 ;;
695+ amd64p32) return 0 ;;
696+ esac
697+ log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value."
698+ return 1
699+}
700+untar() {
701+ tarball=$1
702+ case "${tarball}" in
703+ *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
704+ *.tar) tar --no-same-owner -xf "${tarball}" ;;
705+ *.zip) unzip "${tarball}" ;;
706+ *)
707+ log_err "untar unknown archive format for ${tarball}"
708+ return 1
709+ ;;
710+ esac
711+}
712+http_download_curl() {
713+ local_file=$1
714+ source_url=$2
715+ header=$3
716+ if [ -z "$header" ]; then
717+ code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
718+ else
719+ code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
720+ fi
721+ if [ "$code" != "200" ]; then
722+ log_debug "http_download_curl received HTTP status $code"
723+ return 1
724+ fi
725+ return 0
726+}
727+http_download_wget() {
728+ local_file=$1
729+ source_url=$2
730+ header=$3
731+ if [ -z "$header" ]; then
732+ wget -q -O "$local_file" "$source_url"
733+ else
734+ wget -q --header "$header" -O "$local_file" "$source_url"
735+ fi
736+}
737+http_download() {
738+ log_debug "http_download $2"
739+ if is_command curl; then
740+ http_download_curl "$@"
741+ return
742+ elif is_command wget; then
743+ http_download_wget "$@"
744+ return
745+ fi
746+ log_crit "http_download unable to find wget or curl"
747+ return 1
748+}
749+http_copy() {
750+ tmp=$(mktemp)
751+ http_download "${tmp}" "$1" "$2" || return 1
752+ body=$(cat "$tmp")
753+ rm -f "${tmp}"
754+ echo "$body"
755+}
756+github_release() {
757+ owner_repo=$1
758+ version=$2
759+ test -z "$version" && version="latest"
760+ giturl="https://github.com/${owner_repo}/releases/${version}"
761+ json=$(http_copy "$giturl" "Accept:application/json")
762+ test -z "$json" && return 1
763+ version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
764+ test -z "$version" && return 1
765+ echo "$version"
766+}
767+hash_sha256() {
768+ TARGET=${1:-/dev/stdin}
769+ if is_command gsha256sum; then
770+ hash=$(gsha256sum "$TARGET") || return 1
771+ echo "$hash" | cut -d ' ' -f 1
772+ elif is_command sha256sum; then
773+ hash=$(sha256sum "$TARGET") || return 1
774+ echo "$hash" | cut -d ' ' -f 1
775+ elif is_command shasum; then
776+ hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
777+ echo "$hash" | cut -d ' ' -f 1
778+ elif is_command openssl; then
779+ hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
780+ echo "$hash" | cut -d ' ' -f a
781+ else
782+ log_crit "hash_sha256 unable to find command to compute sha-256 hash"
783+ return 1
784+ fi
785+}
786+hash_sha256_verify() {
787+ TARGET=$1
788+ checksums=$2
789+ if [ -z "$checksums" ]; then
790+ log_err "hash_sha256_verify checksum file not specified in arg2"
791+ return 1
792+ fi
793+ BASENAME=${TARGET##*/}
794+ want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
795+ if [ -z "$want" ]; then
796+ log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
797+ return 1
798+ fi
799+ got=$(hash_sha256 "$TARGET")
800+ if [ "$want" != "$got" ]; then
801+ log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
802+ return 1
803+ fi
804+}
805+cat /dev/null <<EOF
806+------------------------------------------------------------------------
807+End of functions from https://github.com/client9/shlib
808+------------------------------------------------------------------------
809+EOF
810+
811+PROJECT_NAME="golangci-lint"
812+OWNER=golangci
813+REPO="golangci-lint"
814+BINARY=golangci-lint
815+FORMAT=tar.gz
816+OS=$(uname_os)
817+ARCH=$(uname_arch)
818+PREFIX="$OWNER/$REPO"
819+
820+# use in logging routines
821+log_prefix() {
822+ echo "$PREFIX"
823+}
824+PLATFORM="${OS}/${ARCH}"
825+GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
826+
827+uname_os_check "$OS"
828+uname_arch_check "$ARCH"
829+
830+parse_args "$@"
831+
832+get_binaries
833+
834+tag_to_version
835+
836+adjust_format
837+
838+adjust_os
839+
840+adjust_arch
841+
842+log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
843+
844+NAME=${BINARY}-${VERSION}-${OS}-${ARCH}
845+TARBALL=${NAME}.${FORMAT}
846+TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
847+CHECKSUM=${PROJECT_NAME}-${VERSION}-checksums.txt
848+CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
849+
850+
851+execute

Subscribers

People subscribed via source and target branches