Skip to content

Commit

Permalink
feat: start the blkid work
Browse files Browse the repository at this point in the history
This first piece implements filesystem detection.

Signed-off-by: Andrey Smirnov <[email protected]>
  • Loading branch information
smira committed Feb 20, 2024
1 parent aa55391 commit f51033d
Show file tree
Hide file tree
Showing 24 changed files with 1,178 additions and 23 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2024-02-05T11:19:51Z by kres 0e666ea.
# Generated on 2024-02-09T14:38:27Z by kres latest.

*
!blkid
!block
!go.mod
!go.sum
!.golangci.yml
5 changes: 3 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2024-02-05T11:37:35Z by kres 0e666ea-dirty.
# Generated on 2024-02-09T14:40:42Z by kres b787f0e-dirty.

name: default
concurrency:
Expand Down Expand Up @@ -31,7 +31,7 @@ jobs:
if: (!startsWith(github.head_ref, 'renovate/') && !startsWith(github.head_ref, 'dependabot/'))
services:
buildkitd:
image: moby/buildkit:v0.12.4
image: moby/buildkit:v0.12.5
options: --privileged
ports:
- 1234:1234
Expand All @@ -49,6 +49,7 @@ jobs:
with:
driver: remote
endpoint: tcp://localhost:1234
timeout-minutes: 1
- name: base
run: |
make base
Expand Down
5 changes: 2 additions & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2024-02-05T11:19:51Z by kres 0e666ea.
# Generated on 2024-02-09T14:38:27Z by kres latest.

# options for analysis running
run:
Expand Down Expand Up @@ -74,8 +74,6 @@ linters-settings:
govet:
check-shadowing: true
enable-all: true
disable:
- loopclosure
lll:
line-length: 200
tab-width: 4
Expand Down Expand Up @@ -153,6 +151,7 @@ linters:
- inamedparam
- testifylint # complains about our assert recorder and has a number of false positives for assert.Greater(t, thing, 1)
- protogetter # complains about us using Value field on typed spec, instead of GetValue which has a different signature
- perfsprint # complains about us using fmt.Sprintf in non-performance critical code, updating just kres took too long
# abandoned linters for which golangci shows the warning that the repo is archived by the owner
- interfacer
- maligned
Expand Down
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2024-02-05T11:19:51Z by kres 0e666ea.
# Generated on 2024-02-09T14:38:27Z by kres latest.

ARG TOOLCHAIN

Expand Down Expand Up @@ -47,6 +47,7 @@ RUN cd .
RUN --mount=type=cache,target=/go/pkg go mod download
RUN --mount=type=cache,target=/go/pkg go mod verify
COPY ./blkid ./blkid
COPY ./block ./block
RUN --mount=type=cache,target=/go/pkg go list -mod=readonly all >/dev/null

# runs gofumpt
Expand Down
42 changes: 29 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2024-02-05T11:19:51Z by kres 0e666ea.
# Generated on 2024-02-20T17:27:50Z by kres 615351f.

# common variables

Expand All @@ -14,20 +14,19 @@ WITH_RACE ?= false
REGISTRY ?= ghcr.io
USERNAME ?= siderolabs
REGISTRY_AND_USERNAME ?= $(REGISTRY)/$(USERNAME)
PROTOBUF_GO_VERSION ?= 1.31.0
PROTOBUF_GO_VERSION ?= 1.32.0
GRPC_GO_VERSION ?= 1.3.0
GRPC_GATEWAY_VERSION ?= 2.18.1
VTPROTOBUF_VERSION ?= 0.5.0
DEEPCOPY_VERSION ?= v0.5.5
GOLANGCILINT_VERSION ?= v1.55.2
GOFUMPT_VERSION ?= v0.5.0
GO_VERSION ?= 1.21.5
GOIMPORTS_VERSION ?= v0.16.1
GRPC_GATEWAY_VERSION ?= 2.19.1
VTPROTOBUF_VERSION ?= 0.6.0
DEEPCOPY_VERSION ?= v0.5.6
GOLANGCILINT_VERSION ?= v1.56.2
GOFUMPT_VERSION ?= v0.6.0
GO_VERSION ?= 1.22.0
GOIMPORTS_VERSION ?= v0.18.0
GO_BUILDFLAGS ?=
GO_LDFLAGS ?=
CGO_ENABLED ?= 0
GOTOOLCHAIN ?= local
GOEXPERIMENT ?= loopvar
TESTPKGS ?= ./...
KRES_IMAGE ?= ghcr.io/siderolabs/kres:latest
CONFORMANCE_IMAGE ?= ghcr.io/siderolabs/conform:latest
Expand Down Expand Up @@ -65,7 +64,7 @@ COMMON_ARGS += --build-arg=GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)"
COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)"
COMMON_ARGS += --build-arg=GOFUMPT_VERSION="$(GOFUMPT_VERSION)"
COMMON_ARGS += --build-arg=TESTPKGS="$(TESTPKGS)"
TOOLCHAIN ?= docker.io/golang:1.21-alpine
TOOLCHAIN ?= docker.io/golang:1.22-alpine

# help menu

Expand All @@ -88,6 +87,23 @@ To create a builder instance, run:

docker buildx create --name local --use

If running builds that needs to be cached aggresively create a builder instance with the following:

docker buildx create --name local --use --config=config.toml

config.toml contents:

[worker.oci]
gc = true
gckeepstorage = 50000

[[worker.oci.gcpolicy]]
keepBytes = 10737418240
keepDuration = 604800
filters = [ "type==source.local", "type==exec.cachemount", "type==source.git.checkout"]
[[worker.oci.gcpolicy]]
all = true
keepBytes = 53687091200

If you already have a compatible builder instance, you may use that instead.

Expand All @@ -109,7 +125,7 @@ endif
ifneq (, $(filter $(WITH_DEBUG), t true TRUE y yes 1))
GO_BUILDFLAGS += -tags sidero.debug
else
GO_LDFLAGS += -s -w
GO_LDFLAGS += -s
endif

all: unit-tests lint
Expand All @@ -133,7 +149,7 @@ lint-gofumpt: ## Runs gofumpt linter.
.PHONY: fmt
fmt: ## Formats the source code
@docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) \
bash -c "export GOEXPERIMENT=loopvar; export GOTOOLCHAIN=local; \
bash -c "export GOTOOLCHAIN=local; \
export GO111MODULE=on; export GOPROXY=https://proxy.golang.org; \
go install mvdan.cc/gofumpt@$(GOFUMPT_VERSION) && \
gofumpt -w ."
Expand Down
33 changes: 33 additions & 0 deletions blkid/blkdid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Package blkid provides information about blockdevice filesystem types and IDs.
package blkid

import (
"github.com/google/uuid"

"github.com/siderolabs/go-blockdevice/v2/block"
)

// Info represents the result of the probe.
type Info struct { //nolint:govet
// Link to the block device, only if the probed file is a blockdevice.
BlockDevice *block.Device

// Overall size of the probed device (in bytes).
Size uint64

// Optimal I/O size for the device (in bytes).
IOSize uint64

// TODO: API might be different.
Name string
UUID *uuid.UUID
Label *string

BlockSize uint32
FilesystemBlockSize uint32
FilesystemSize uint64
}
73 changes: 73 additions & 0 deletions blkid/blkid_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//go:build linux

package blkid

import (
"fmt"
"os"
"syscall"

"golang.org/x/sys/unix"

"github.com/siderolabs/go-blockdevice/v2/block"
)

// ProbePath returns the probe information for the specified path.
func ProbePath(devpath string) (*Info, error) {
f, err := os.OpenFile(devpath, os.O_RDONLY|unix.O_CLOEXEC|unix.O_NONBLOCK, 0)
if err != nil {
return nil, err
}

defer f.Close() //nolint:errcheck

return Probe(f)
}

// Probe returns the probe information for the specified file.
func Probe(f *os.File) (*Info, error) {
unix.Fadvise(int(f.Fd()), 0, 0, unix.FADV_RANDOM) //nolint:errcheck // best-effort: we don't care if this fails

st, err := f.Stat()
if err != nil {
return nil, fmt.Errorf("failed to stat: %w", err)
}

info := &Info{}

sysStat := st.Sys().(*syscall.Stat_t) //nolint:errcheck,forcetypeassert // we know it's a syscall.Stat_t

switch sysStat.Mode & unix.S_IFMT {
case unix.S_IFBLK:
// block device, initialize full support
info.BlockDevice = block.NewFromFile(f)

if size, err := info.BlockDevice.GetSize(); err == nil {
info.Size = size
} else {
return nil, fmt.Errorf("failed to get block device size: %w", err)
}

if ioSize, err := info.BlockDevice.GetIOSize(); err == nil {
info.IOSize = ioSize
} else {
return nil, fmt.Errorf("failed to get block device I/O size: %w", err)
}
case unix.S_IFREG:
// regular file (an image?), so use different settings
info.Size = uint64(st.Size())
info.IOSize = block.DefaultBlockSize
default:
return nil, fmt.Errorf("unsupported file type: %s", st.Mode().Type())
}

if err := info.probe(f, 0, info.Size); err != nil {
return nil, fmt.Errorf("failed to probe: %w", err)
}

return info, nil
}
Loading

0 comments on commit f51033d

Please sign in to comment.