Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.29 and go 1.18 base + #566 (round robin dns) + #564 (revamp of build through go install module buildinfo) #560

Merged
merged 6 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ version: 2
defaultEnv: &defaultEnv
docker:
# specify the version
- image: docker.io/fortio/fortio.build:v39
- image: docker.io/fortio/fortio.build:v40
working_directory: /go/src/fortio.org/fortio

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag_name="${{ github.ref }}"
tag_name="${GITHUB_REF##*/}"
echo "tag_name=$tag_name"
gh release upload "${tag_name}" release/*.{tgz,zip,rpm,deb,gz}
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ linters:
- wrapcheck
- exhaustivestruct
- tagliatelle
- nonamedreturns
# TODO consider putting these back, when they stop being bugged (ifshort, wastedassign,...)
- paralleltest
- thelper
Expand Down
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Build the binaries in larger image
FROM docker.io/fortio/fortio.build:v39 as build
FROM docker.io/fortio/fortio.build:v40 as build
WORKDIR /go/src/fortio.org
COPY . fortio
ARG MODE=install
# We moved a lot of the logic into the Makefile so it can be reused in brew
# but that also couples the 2, this expects to find binaries in the right place etc
RUN make -C fortio official-build-version BUILD_DIR=/build OFFICIAL_BIN=../fortio_go_latest.bin
RUN make -C fortio official-build-version BUILD_DIR=/build MODE=${MODE}

# Minimal image with just the binary and certs
FROM scratch as release
Expand All @@ -13,7 +14,7 @@ COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# TODO: get rid of *.bak, *~ and other spurious non source files
#COPY --from=build /go/src/fortio.org/fortio/ui/static /usr/share/fortio/static
#COPY --from=build /go/src/fortio.org/fortio/ui/templates /usr/share/fortio/templates
COPY --from=build /go/src/fortio.org/fortio_go_latest.bin /usr/bin/fortio
COPY --from=build /build/result/fortio /usr/bin/fortio
EXPOSE 8078
EXPOSE 8079
EXPOSE 8080
Expand Down
6 changes: 2 additions & 4 deletions Dockerfile.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Dependencies and linters for build:
FROM golang:1.17.9
FROM golang:1.18.2
# Need gcc for -race test (and some linters though those work with CGO_ENABLED=0)
RUN apt-get -y update && \
apt-get --no-install-recommends -y upgrade && \
Expand All @@ -11,9 +11,7 @@ RUN gem install --no-document fpm
RUN go version # check it's indeed the version we expect

# golangci-lint
# See https://github.com/golangci/golangci-lint/issues/2673 (and 2374)
# Use 1.44.2 which works on arm while 1.45.2 doesn't... somehow
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.2
RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
RUN golangci-lint version

# Docker:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.echosrv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build the binaries in larger image
FROM docker.io/fortio/fortio.build:v39 as build
FROM docker.io/fortio/fortio.build:v40 as build
WORKDIR /go/src/fortio.org
COPY . fortio
RUN make -C fortio official-build-version BUILD_DIR=/build OFFICIAL_TARGET=fortio.org/fortio/echosrv OFFICIAL_BIN=../echosrv.bin
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.fcurl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build the binaries in larger image
FROM docker.io/fortio/fortio.build:v39 as build
FROM docker.io/fortio/fortio.build:v40 as build
WORKDIR /go/src/fortio.org
COPY . fortio
# fcurl should not need vendor/no dependencies
Expand Down
6 changes: 0 additions & 6 deletions Dockerfile.test

This file was deleted.

61 changes: 28 additions & 33 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
IMAGES=echosrv fcurl # plus the combo image / Dockerfile without ext.

DOCKER_PREFIX := docker.io/fortio/fortio
BUILD_IMAGE_TAG := v39
BUILD_IMAGE_TAG := v40
BUILDX_PLATFORMS := linux/amd64,linux/arm64,linux/ppc64le,linux/s390x
BUILDX_POSTFIX :=
ifeq '$(shell echo $(BUILDX_PLATFORMS) | awk -F "," "{print NF-1}")' '0'
Expand Down Expand Up @@ -98,7 +98,7 @@ all: test go-install lint docker-version docker-push-internal
# (bump BUILD_IMAGE_TAG), also change this list if the image is used in
# more places.
FILES_WITH_IMAGE:= .circleci/config.yml Dockerfile Dockerfile.echosrv \
Dockerfile.test Dockerfile.fcurl release/Dockerfile.in Webtest.sh
Dockerfile.fcurl release/Dockerfile.in Webtest.sh
# then run make update-build-image and check the diff, etc... see release/README.md
update-build-image:
docker buildx create --use
Expand All @@ -118,7 +118,7 @@ docker-version:

docker-internal: dependencies
@echo "### Now building $(DOCKER_TAG)"
docker buildx build --platform $(BUILDX_PLATFORMS) -f Dockerfile$(IMAGE) -t $(DOCKER_TAG) $(BUILDX_POSTFIX) .
docker buildx build --platform $(BUILDX_PLATFORMS) --build-arg MODE=$(MODE) -f Dockerfile$(IMAGE) -t $(DOCKER_TAG) $(BUILDX_POSTFIX) .

docker-push-internal: docker-internal docker-buildx-push

Expand All @@ -137,16 +137,19 @@ release: dist

# Targets used for official builds (initially from Dockerfile)
BUILD_DIR := /tmp/fortio_build
LIB_DIR := /usr/share/fortio
DATA_DIR := .
OFFICIAL_BIN := ../fortio.bin
BUILD_DIR_ABS := $(abspath $(BUILD_DIR))
BUILD_DIR_BIN := $(BUILD_DIR_ABS)/bin
OFFICIAL_BIN ?= $(BUILD_DIR)/result/fortio
OFFICIAL_DIR ?= $(dir $(OFFICIAL_BIN))

GOOS :=
GO_BIN := go
GIT_TAG ?= $(shell git describe --tags --match 'v*' --dirty)
DIST_VERSION ?= $(shell echo $(GIT_TAG) | sed -e "s/^v//")
GIT_SHA ?= $(shell git rev-parse HEAD)
# Main/default binary to build: (can be changed to build fcurl or echosrv instead)
OFFICIAL_TARGET := fortio.org/fortio
MODE ?= install

debug-tags:
@echo "GIT_TAG=$(GIT_TAG)"
Expand All @@ -159,38 +162,34 @@ echo-version:
echo-package-version:
@echo "$(DIST_VERSION)" | sed -e "s/-/_/g"

# Putting spaces in linker replaced variables is hard but does work.
# This sets up the static directory outside of the go source tree and
# the default data directory to a /var/lib/... volume
# + rest of build time/git/version magic.

$(BUILD_DIR)/build-info.txt:
-mkdir -p $(BUILD_DIR)
echo "$(shell date +'%Y-%m-%d %H:%M') $(GIT_SHA)" > $@
$(BUILD_DIR):
mkdir -p $(BUILD_DIR)

# This needs to be redone between build targets (so the windows build for instance gets the right LIB_DIR)
$(BUILD_DIR)/link-flags.txt: $(BUILD_DIR)/build-info.txt
echo "-s -X main.defaultDataDir=$(DATA_DIR) \
-X \"fortio.org/fortio/version.buildInfo=$(shell cat $<)\" \
-X fortio.org/fortio/version.version=$(DIST_VERSION)" | tee $@
$(OFFICIAL_DIR):
mkdir -p $(OFFICIAL_DIR)

.PHONY: official-build official-build-internal official-build-version official-build-clean clean-link-flags
.PHONY: official-build official-build-internal official-build-version official-build-clean

official-build: clean-link-flags official-build-internal
official-build: official-build-internal

# Fix 474
clean-link-flags:
-$(RM) $(BUILD_DIR)/link-flags.txt

official-build-internal: $(BUILD_DIR)/link-flags.txt
official-build-internal: $(BUILD_DIR) $(OFFICIAL_DIR)
$(GO_BIN) version
CGO_ENABLED=0 GOOS=$(GOOS) $(GO_BIN) build -a -ldflags '$(shell cat $(BUILD_DIR)/link-flags.txt)' -o $(OFFICIAL_BIN) $(OFFICIAL_TARGET)
ifeq ($(MODE),install)
GOPATH=$(BUILD_DIR_ABS) CGO_ENABLED=0 GOOS=$(GOOS) $(GO_BIN) install -a -ldflags -s $(OFFICIAL_TARGET)@v$(DIST_VERSION)
# rename when building cross architecture (on windows it has .exe suffix thus the *)
ls -lR $(BUILD_DIR_BIN)
-mv -f $(BUILD_DIR_BIN)/*_*/fortio* $(BUILD_DIR_BIN)
-rmdir $(BUILD_DIR_BIN)/*_*
mv -f $(BUILD_DIR_BIN)/fortio* $(OFFICIAL_DIR)
else
CGO_ENABLED=0 GOOS=$(GOOS) $(GO_BIN) build -a -ldflags -s -o $(OFFICIAL_BIN) $(OFFICIAL_TARGET)
endif

official-build-version: official-build
$(OFFICIAL_BIN) version

official-build-clean:
-$(RM) $(BUILD_DIR)/build-info.txt $(BUILD_DIR)/link-flags.txt $(OFFICIAL_BIN) release/Makefile
-$(RM) $(OFFICIAL_BIN) release/Makefile

# Create a complete source tree with naming matching debian package conventions
TAR ?= tar # on macos need gtar to get --owner
Expand Down Expand Up @@ -231,16 +230,12 @@ install: official-install
.PHONY: install official-install

BIN_INSTALL_DIR = $(DESTDIR)/usr/bin
LIB_INSTALL_DIR = $(DESTDIR)$(LIB_DIR)
MAN_INSTALL_DIR = $(DESTDIR)/usr/share/man/man1
#DATA_INSTALL_DIR = $(DESTDIR)$(DATA_DIR)
BIN_INSTALL_EXEC = fortio

official-install: official-build-clean official-build-version
-mkdir -p $(BIN_INSTALL_DIR) $(MAN_INSTALL_DIR) # $(LIB_INSTALL_DIR) $(DATA_INSTALL_DIR)
# -chmod 1777 $(DATA_INSTALL_DIR)
-mkdir -p $(BIN_INSTALL_DIR) $(MAN_INSTALL_DIR)
cp $(OFFICIAL_BIN) $(BIN_INSTALL_DIR)/$(BIN_INSTALL_EXEC)
#cp -r ui/templates ui/static $(LIB_INSTALL_DIR)
cp docs/fortio.1 $(MAN_INSTALL_DIR)

# Test distribution (only used by maintainer)
Expand Down
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ You can install from source:


```shell
curl -L https://github.com/fortio/fortio/releases/download/v1.28.0/fortio-linux_amd64-1.28.0.tgz \
curl -L https://github.com/fortio/fortio/releases/download/v1.29.0/fortio-linux_amd64-1.29.0.tgz \
| sudo tar -C / -xvzpf -
# or the debian package
wget https://github.com/fortio/fortio/releases/download/v1.28.0/fortio_1.28.0_amd64.deb
dpkg -i fortio_1.28.0_amd64.deb
wget https://github.com/fortio/fortio/releases/download/v1.29.0/fortio_1.29.0_amd64.deb
dpkg -i fortio_1.29.0_amd64.deb
# or the rpm
rpm -i https://github.com/fortio/fortio/releases/download/v1.28.0/fortio-1.28.0-1.x86_64.rpm
rpm -i https://github.com/fortio/fortio/releases/download/v1.29.0/fortio-1.29.0-1.x86_64.rpm
# and more, see assets in release page
```

Expand All @@ -66,7 +66,7 @@ On a MacOS you can also install Fortio using [Homebrew](https://brew.sh/):
brew install fortio
```

On Windows, download https://github.com/fortio/fortio/releases/download/v1.28.0/fortio_win_1.28.0.zip and extract `fortio.exe` to any location, then using the Windows Command Prompt:
On Windows, download https://github.com/fortio/fortio/releases/download/v1.29.0/fortio_win_1.29.0.zip and extract `fortio.exe` to any location, then using the Windows Command Prompt:
```
fortio.exe server
```
Expand Down Expand Up @@ -114,7 +114,7 @@ Full list of command line flags (`fortio help`):
<details>
<!-- use release/updateFlags.sh to update this section -->
<pre>
Φορτίο 1.28.0 usage:
Φορτίο 1.29.0 usage:
where command is one of: load (load testing), server (starts ui, http-echo,
redirect, proxies, tcp-echo and grpc ping servers), tcp-echo (only the tcp-echo
server), report (report only UI server), redirect (only the redirect server),
Expand Down Expand Up @@ -197,7 +197,7 @@ http)
which service string to pass to health check
-http-port port
http echo server port. Can be in the form of host:port, ip:port, port
or /unix/domain/path. (default "8080")
or /unix/domain/path or "disabled". (default "8080")
-http1.0
Use http1.0 (instead of http 1.1)
-httpbufferkb kbytes
Expand Down Expand Up @@ -279,6 +279,9 @@ properly). Can be in the form of host:port, ip:port, port or "disabled" to
disable the feature. (default "8081")
-resolve IP
Resolve host name to this IP
-resolve-ip-type type
Resolve type: ip4 for ipv4, ip6 for ipv6 only, use ip for both (default
ip4)
-runid int
Optional RunID to add to json result and auto save filename, to match
server mode
Expand Down
4 changes: 2 additions & 2 deletions Webtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ set -x
# Check we can build the image
NATIVE_PLATFORM=$(docker buildx --builder default inspect | tail -1 | sed -e "s/Platforms: //" -e "s/,//g" | awk '{print $1}')
echo "Building for $NATIVE_PLATFORM"
make docker-internal TAG=webtest BUILDX_PLATFORMS="$NATIVE_PLATFORM" || exit 1
make docker-internal TAG=webtest BUILDX_PLATFORMS="$NATIVE_PLATFORM" MODE=dev || exit 1
FORTIO_UI_PREFIX=/newprefix/ # test the non default prefix (not /fortio/)
FILE_LIMIT=25 # must be low to detect leaks, go 1.14 seems to need more than go1.8 (!)
LOGLEVEL=info # change to debug to debug
Expand Down Expand Up @@ -117,7 +117,7 @@ docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping localhost
PPROF_URL="$BASE_URL/debug/pprof/heap?debug=1"
$CURL "$PPROF_URL" | grep -i TotalAlloc # should find this in memory profile
# creating dummy container to hold a volume for test certs due to remote docker bind mount limitation.
docker create -v $TEST_CERT_VOL --name $DOCKERSECVOLNAME docker.io/fortio/fortio.build:v39 /bin/true # cleaned up by name
docker create -v $TEST_CERT_VOL --name $DOCKERSECVOLNAME docker.io/fortio/fortio.build:v40 /bin/true # cleaned up by name
# copying cert files into the certs volume of the dummy container
for f in ca.crt server.crt server.key; do docker cp "$PWD/cert-tmp/$f" "$DOCKERSECVOLNAME:$TEST_CERT_VOL/$f"; done
# start server in secure grpc mode. uses non-default ports to avoid conflicts with fortio_server container.
Expand Down
2 changes: 1 addition & 1 deletion bincommon/commonflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func SharedMain(usage func(io.Writer, ...interface{})) {
// so `fortio version -s` is the short version; everything else is long/full
fmt.Println(version.Short())
} else {
fmt.Println(version.Long())
fmt.Println(version.Full())
}
os.Exit(0)
}
Expand Down
3 changes: 2 additions & 1 deletion dflag/configmap/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ type (

// eventually tries a given Assert function 5 times over the period of time.
func eventually(t *testing.T, duration time.Duration,
af assertFunc, expected interface{}, actual getter, msgFmt string, msgArgs ...interface{}) {
af assertFunc, expected interface{}, actual getter, msgFmt string, msgArgs ...interface{},
) {
increment := duration / 5
for i := 0; i < 5; i++ {
time.Sleep(increment)
Expand Down
3 changes: 2 additions & 1 deletion dflag/dynstringset.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ func (d *DynStringSetValue) WithValidator(validator func(map[string]struct{}) er
// WithNotifier adds a function that is called every time a new value is successfully set.
// Each notifier is executed asynchronously in a new go-routine.
func (d *DynStringSetValue) WithNotifier(notifier func(oldValue map[string]struct{},
newValue map[string]struct{})) *DynStringSetValue {
newValue map[string]struct{}),
) *DynStringSetValue {
d.notifier = notifier
return d
}
Expand Down
5 changes: 3 additions & 2 deletions fhttp/http_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -676,14 +676,15 @@ func (c *FastClient) connect() net.Conn {
c.socketCount++
var socket net.Conn
var err error
d := &net.Dialer{Timeout: c.reqTimeout}
if c.https {
socket, err = tls.Dial(c.dest.Network(), c.dest.String(), c.tlsConfig)
socket, err = tls.DialWithDialer(d, c.dest.Network(), c.dest.String(), c.tlsConfig)
if err != nil {
log.Errf("[%d] Unable to TLS connect to %v : %v", c.id, c.dest, err)
return nil
}
} else {
socket, err = net.Dial(c.dest.Network(), c.dest.String())
socket, err = d.Dial(c.dest.Network(), c.dest.String())
if err != nil {
log.Errf("[%d] Unable to connect to %v : %v", c.id, c.dest, err)
return nil
Expand Down
13 changes: 10 additions & 3 deletions fhttp/http_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,22 +172,29 @@ func closingServer(listener net.Listener) error {
// Port can include binding address and/or be port 0.
func HTTPServer(name string, port string) (*http.ServeMux, net.Addr) {
m := http.NewServeMux()
return m, HTTPServerWithHandler(name, port, m)
}

// HTTPServerWithHandler creates and h2c compatible server named name on address/port port.
// Port can include binding address and/or be port 0.
// Takes in a handler.
func HTTPServerWithHandler(name string, port string, hdlr http.Handler) net.Addr {
h2s := &http2.Server{}
s := &http.Server{
IdleTimeout: serverIdleTimeout.Get(),
Handler: h2c.NewHandler(m, h2s),
Handler: h2c.NewHandler(hdlr, h2s),
}
listener, addr := fnet.Listen(name, port)
if listener == nil {
return nil, nil // error already logged
return nil // error already logged
}
go func() {
err := s.Serve(listener)
if err != nil {
log.Fatalf("Unable to serve %s on %s: %v", name, addr.String(), err)
}
}()
return m, addr
return addr
}

// DynamicHTTPServer listens on an available port, sets up an http or a closing
Expand Down
9 changes: 5 additions & 4 deletions fhttp/httprunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func RunHTTPTest(o *HTTPRunnerOptions) (*HTTPRunnerResults, error) {
log.Infof("Starting http test for %s with %d threads at %.1f qps and %s warmup", o.URL, o.NumThreads, o.QPS, warmupMode)
r := periodic.NewPeriodicRunner(&o.RunnerOptions)
defer r.Options().Abort()
numThreads := r.Options().NumThreads
numThreads := r.Options().NumThreads // can change during run for c > 2 n
o.HTTPOptions.Init(o.URL)
out := r.Options().Out // Important as the default value is set from nil to stdout inside NewPeriodicRunner
total := HTTPRunnerResults{
Expand Down Expand Up @@ -180,8 +180,9 @@ func RunHTTPTest(o *HTTPRunnerOptions) (*HTTPRunnerResults, error) {
fm.Close()
_, _ = fmt.Fprintf(out, "Wrote profile data to %s.{cpu|mem}\n", o.Profiler)
}
// Numthreads may have reduced but it should be ok to accumulate 0s from
// unused ones. We also must cleanup all the created clients.
// Numthreads may have reduced:
numThreads = total.RunnerResults.NumThreads
// But we also must cleanup all the created clients.
keys := []int{}
for i := 0; i < numThreads; i++ {
// Get the report on the IP address each thread use to send traffic
Expand Down Expand Up @@ -211,7 +212,7 @@ func RunHTTPTest(o *HTTPRunnerOptions) (*HTTPRunnerResults, error) {
return total.IPCountMap[ipList[i]] > total.IPCountMap[ipList[j]]
})

// Cleanup state:
// Cleanup state: (original num thread)
r.Options().ReleaseRunners()
sort.Ints(keys)
totalCount := float64(total.DurationHistogram.Count)
Expand Down