From 7e3fc8f7e0a7d083ee183eec68cdfcc027213c37 Mon Sep 17 00:00:00 2001 From: Jack Lin Date: Mon, 11 Mar 2024 16:11:06 +0800 Subject: [PATCH] chore(vendor): update go-common-libs/go-iscsi-utils and resolve breaking changes ref: longhorn/longhorn 7960 Signed-off-by: Jack Lin --- app/daemon.go | 13 +- controller/engine_controller.go | 6 +- controller/monitor/disk_monitor.go | 8 +- controller/monitor/disk_utils.go | 67 +- controller/monitor/fake_disk_monitor.go | 7 +- controller/orphan_controller.go | 9 +- controller/replica_controller.go | 5 +- controller/setting_controller.go | 6 +- csi/crypto/crypto.go | 53 +- csi/crypto/luks.go | 83 -- engineapi/backups.go | 8 +- engineapi/engine.go | 11 +- go.mod | 31 +- go.sum | 154 ++-- types/device.go | 4 +- types/types.go | 11 +- util/os.go | 46 -- util/os_test.go | 59 -- util/util.go | 295 ++----- util/util_test.go | 131 ++- vendor/github.com/go-logr/logr/README.md | 113 ++- vendor/github.com/go-logr/logr/SECURITY.md | 18 + vendor/github.com/go-logr/logr/funcr/funcr.go | 48 +- vendor/github.com/go-logr/logr/logr.go | 35 +- .../go-logr/logr/slogr/sloghandler.go | 168 ++++ vendor/github.com/go-logr/logr/slogr/slogr.go | 108 +++ .../github.com/go-logr/logr/slogr/slogsink.go | 122 +++ vendor/github.com/go-ole/go-ole/.travis.yml | 8 + vendor/github.com/go-ole/go-ole/ChangeLog.md | 49 ++ vendor/github.com/go-ole/go-ole/LICENSE | 21 + vendor/github.com/go-ole/go-ole/README.md | 46 ++ vendor/github.com/go-ole/go-ole/appveyor.yml | 54 ++ vendor/github.com/go-ole/go-ole/com.go | 344 ++++++++ vendor/github.com/go-ole/go-ole/com_func.go | 174 ++++ vendor/github.com/go-ole/go-ole/connect.go | 192 +++++ vendor/github.com/go-ole/go-ole/constants.go | 153 ++++ vendor/github.com/go-ole/go-ole/error.go | 51 ++ vendor/github.com/go-ole/go-ole/error_func.go | 8 + .../github.com/go-ole/go-ole/error_windows.go | 24 + vendor/github.com/go-ole/go-ole/guid.go | 284 +++++++ .../go-ole/go-ole/iconnectionpoint.go | 20 + .../go-ole/go-ole/iconnectionpoint_func.go | 21 + .../go-ole/go-ole/iconnectionpoint_windows.go | 43 + .../go-ole/iconnectionpointcontainer.go | 17 + .../go-ole/iconnectionpointcontainer_func.go | 11 + .../iconnectionpointcontainer_windows.go | 25 + vendor/github.com/go-ole/go-ole/idispatch.go | 94 +++ .../go-ole/go-ole/idispatch_func.go | 19 + .../go-ole/go-ole/idispatch_windows.go | 202 +++++ .../github.com/go-ole/go-ole/ienumvariant.go | 19 + .../go-ole/go-ole/ienumvariant_func.go | 19 + .../go-ole/go-ole/ienumvariant_windows.go | 63 ++ .../github.com/go-ole/go-ole/iinspectable.go | 18 + .../go-ole/go-ole/iinspectable_func.go | 15 + .../go-ole/go-ole/iinspectable_windows.go | 72 ++ .../go-ole/go-ole/iprovideclassinfo.go | 21 + .../go-ole/go-ole/iprovideclassinfo_func.go | 7 + .../go-ole/iprovideclassinfo_windows.go | 21 + vendor/github.com/go-ole/go-ole/itypeinfo.go | 34 + .../go-ole/go-ole/itypeinfo_func.go | 7 + .../go-ole/go-ole/itypeinfo_windows.go | 21 + vendor/github.com/go-ole/go-ole/iunknown.go | 57 ++ .../github.com/go-ole/go-ole/iunknown_func.go | 19 + .../go-ole/go-ole/iunknown_windows.go | 58 ++ vendor/github.com/go-ole/go-ole/ole.go | 190 +++++ .../go-ole/go-ole/oleutil/connection.go | 100 +++ .../go-ole/go-ole/oleutil/connection_func.go | 10 + .../go-ole/oleutil/connection_windows.go | 58 ++ .../go-ole/go-ole/oleutil/go-get.go | 6 + .../go-ole/go-ole/oleutil/oleutil.go | 127 +++ vendor/github.com/go-ole/go-ole/safearray.go | 27 + .../go-ole/go-ole/safearray_func.go | 211 +++++ .../go-ole/go-ole/safearray_windows.go | 337 ++++++++ .../go-ole/go-ole/safearrayconversion.go | 140 ++++ .../go-ole/go-ole/safearrayslices.go | 33 + vendor/github.com/go-ole/go-ole/utility.go | 101 +++ vendor/github.com/go-ole/go-ole/variables.go | 15 + vendor/github.com/go-ole/go-ole/variant.go | 105 +++ .../github.com/go-ole/go-ole/variant_386.go | 11 + .../github.com/go-ole/go-ole/variant_amd64.go | 12 + .../github.com/go-ole/go-ole/variant_arm.go | 11 + .../github.com/go-ole/go-ole/variant_arm64.go | 13 + .../go-ole/go-ole/variant_date_386.go | 22 + .../go-ole/go-ole/variant_date_amd64.go | 20 + .../go-ole/go-ole/variant_date_arm.go | 22 + .../go-ole/go-ole/variant_date_arm64.go | 23 + .../go-ole/go-ole/variant_ppc64le.go | 12 + .../github.com/go-ole/go-ole/variant_s390x.go | 12 + vendor/github.com/go-ole/go-ole/vt_string.go | 58 ++ vendor/github.com/go-ole/go-ole/winrt.go | 99 +++ vendor/github.com/go-ole/go-ole/winrt_doc.go | 36 + .../golang/protobuf/jsonpb/decode.go | 531 ------------ .../golang/protobuf/jsonpb/encode.go | 560 ------------- .../github.com/golang/protobuf/jsonpb/json.go | 69 -- .../longhorn/go-common-libs/LICENSE | 201 +++++ .../longhorn/go-common-libs/exec/exec.go | 125 +++ .../longhorn/go-common-libs/io/file.go | 243 ++++++ .../longhorn/go-common-libs/ns/crypto.go | 69 ++ .../longhorn/go-common-libs/ns/executor.go | 87 ++ .../longhorn/go-common-libs/ns/file.go | 282 +++++++ .../longhorn/go-common-libs/ns/filelock.go | 143 ++++ .../longhorn/go-common-libs/ns/joiner.go | 379 +++++++++ .../longhorn/go-common-libs/ns/misc.go | 23 + .../longhorn/go-common-libs/ns/sys.go | 99 +++ .../longhorn/go-common-libs/proc/proc.go | 210 +++++ .../longhorn/go-common-libs/sync/filelock.go | 50 ++ .../longhorn/go-common-libs/sys/sys.go | 129 +++ .../longhorn/go-common-libs/test/fake/file.go | 36 + .../go-common-libs/test/fake/namespace.go | 42 + .../go-common-libs/test/fake/system.go | 45 ++ .../longhorn/go-common-libs/types/crypto.go | 7 + .../longhorn/go-common-libs/types/exec.go | 15 + .../longhorn/go-common-libs/types/file.go | 33 + .../longhorn/go-common-libs/types/misc.go | 3 + .../go-common-libs/types/namespace.go | 42 + .../longhorn/go-common-libs/types/proc.go | 12 + .../longhorn/go-common-libs/types/sys.go | 13 + .../longhorn/go-common-libs/utils/grpc.go | 17 + .../go-common-libs/utils/longhorn_naming.go | 11 + .../longhorn/go-common-libs/utils/misc.go | 100 +++ .../longhorn/go-common-libs/utils/mount.go | 14 + .../go-iscsi-helper/iscsi/initiator.go | 118 +-- .../longhorn/go-iscsi-helper/iscsi/target.go | 33 +- .../go-iscsi-helper/types/tgtadm_errors.go | 2 +- .../longhorn/go-iscsi-helper/util/process.go | 59 +- .../longhorn/go-iscsi-helper/util/util.go | 237 +----- .../longhorn/longhorn-engine/pkg/util/util.go | 32 - .../pkg/util/util.go | 9 - .../pkg/crypto/crypto.go | 39 +- .../longhorn-share-manager/pkg/crypto/luks.go | 77 -- .../longhorn-share-manager/pkg/rpc/server.go | 21 +- .../pkg/server/share_manager.go | 13 +- .../github.com/power-devops/perfstat/LICENSE | 23 + .../power-devops/perfstat/c_helpers.c | 159 ++++ .../power-devops/perfstat/c_helpers.h | 58 ++ .../power-devops/perfstat/config.go | 18 + .../power-devops/perfstat/cpustat.go | 98 +++ .../power-devops/perfstat/diskstat.go | 137 ++++ .../github.com/power-devops/perfstat/doc.go | 315 ++++++++ .../power-devops/perfstat/fsstat.go | 31 + .../power-devops/perfstat/helpers.go | 764 ++++++++++++++++++ .../power-devops/perfstat/lparstat.go | 26 + .../power-devops/perfstat/lvmstat.go | 72 ++ .../power-devops/perfstat/memstat.go | 84 ++ .../power-devops/perfstat/netstat.go | 117 +++ .../power-devops/perfstat/procstat.go | 75 ++ .../power-devops/perfstat/sysconf.go | 195 +++++ .../power-devops/perfstat/systemcfg.go | 635 +++++++++++++++ .../power-devops/perfstat/types_cpu.go | 186 +++++ .../power-devops/perfstat/types_disk.go | 176 ++++ .../power-devops/perfstat/types_fs.go | 195 +++++ .../power-devops/perfstat/types_lpar.go | 68 ++ .../power-devops/perfstat/types_lvm.go | 31 + .../power-devops/perfstat/types_memory.go | 101 +++ .../power-devops/perfstat/types_network.go | 163 ++++ .../power-devops/perfstat/types_process.go | 43 + .../power-devops/perfstat/uptime.go | 35 + vendor/github.com/shirou/gopsutil/v3/LICENSE | 61 ++ .../shirou/gopsutil/v3/common/env.go | 23 + .../shirou/gopsutil/v3/disk/disk.go | 98 +++ .../shirou/gopsutil/v3/disk/disk_aix.go | 22 + .../shirou/gopsutil/v3/disk/disk_aix_cgo.go | 76 ++ .../shirou/gopsutil/v3/disk/disk_aix_nocgo.go | 81 ++ .../shirou/gopsutil/v3/disk/disk_darwin.go | 94 +++ .../gopsutil/v3/disk/disk_darwin_cgo.go | 45 ++ .../gopsutil/v3/disk/disk_darwin_nocgo.go | 14 + .../shirou/gopsutil/v3/disk/disk_fallback.go | 30 + .../shirou/gopsutil/v3/disk/disk_freebsd.go | 192 +++++ .../gopsutil/v3/disk/disk_freebsd_386.go | 63 ++ .../gopsutil/v3/disk/disk_freebsd_amd64.go | 66 ++ .../gopsutil/v3/disk/disk_freebsd_arm.go | 63 ++ .../gopsutil/v3/disk/disk_freebsd_arm64.go | 66 ++ .../shirou/gopsutil/v3/disk/disk_linux.go | 561 +++++++++++++ .../shirou/gopsutil/v3/disk/disk_netbsd.go | 152 ++++ .../gopsutil/v3/disk/disk_netbsd_amd64.go | 45 ++ .../gopsutil/v3/disk/disk_netbsd_arm64.go | 45 ++ .../shirou/gopsutil/v3/disk/disk_openbsd.go | 159 ++++ .../gopsutil/v3/disk/disk_openbsd_386.go | 38 + .../gopsutil/v3/disk/disk_openbsd_amd64.go | 36 + .../gopsutil/v3/disk/disk_openbsd_arm.go | 38 + .../gopsutil/v3/disk/disk_openbsd_arm64.go | 38 + .../gopsutil/v3/disk/disk_openbsd_riscv64.go | 40 + .../shirou/gopsutil/v3/disk/disk_solaris.go | 261 ++++++ .../shirou/gopsutil/v3/disk/disk_unix.go | 63 ++ .../shirou/gopsutil/v3/disk/disk_windows.go | 241 ++++++ .../shirou/gopsutil/v3/disk/iostat_darwin.c | 129 +++ .../shirou/gopsutil/v3/disk/iostat_darwin.h | 32 + .../gopsutil/v3/internal/common/binary.go | 637 +++++++++++++++ .../gopsutil/v3/internal/common/common.go | 464 +++++++++++ .../v3/internal/common/common_darwin.go | 66 ++ .../v3/internal/common/common_freebsd.go | 82 ++ .../v3/internal/common/common_linux.go | 353 ++++++++ .../v3/internal/common/common_netbsd.go | 66 ++ .../v3/internal/common/common_openbsd.go | 66 ++ .../v3/internal/common/common_unix.go | 62 ++ .../v3/internal/common/common_windows.go | 304 +++++++ .../gopsutil/v3/internal/common/endian.go | 10 + .../gopsutil/v3/internal/common/sleep.go | 21 + .../gopsutil/v3/internal/common/warnings.go | 30 + vendor/github.com/yusufpapurcu/wmi/LICENSE | 20 + vendor/github.com/yusufpapurcu/wmi/README.md | 6 + .../yusufpapurcu/wmi/swbemservices.go | 261 ++++++ vendor/github.com/yusufpapurcu/wmi/wmi.go | 603 ++++++++++++++ vendor/golang.org/x/sync/errgroup/errgroup.go | 3 + vendor/golang.org/x/sys/unix/aliases.go | 2 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 2 +- .../x/sys/unix/syscall_darwin_libSystem.go | 2 +- .../golang.org/x/sys/unix/syscall_freebsd.go | 12 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 99 +++ vendor/golang.org/x/sys/unix/zerrors_linux.go | 36 +- .../x/sys/unix/zerrors_linux_386.go | 3 + .../x/sys/unix/zerrors_linux_amd64.go | 3 + .../x/sys/unix/zerrors_linux_arm.go | 3 + .../x/sys/unix/zerrors_linux_arm64.go | 3 + .../x/sys/unix/zerrors_linux_loong64.go | 3 + .../x/sys/unix/zerrors_linux_mips.go | 3 + .../x/sys/unix/zerrors_linux_mips64.go | 3 + .../x/sys/unix/zerrors_linux_mips64le.go | 3 + .../x/sys/unix/zerrors_linux_mipsle.go | 3 + .../x/sys/unix/zerrors_linux_ppc.go | 3 + .../x/sys/unix/zerrors_linux_ppc64.go | 3 + .../x/sys/unix/zerrors_linux_ppc64le.go | 3 + .../x/sys/unix/zerrors_linux_riscv64.go | 3 + .../x/sys/unix/zerrors_linux_s390x.go | 3 + .../x/sys/unix/zerrors_linux_sparc64.go | 3 + .../golang.org/x/sys/unix/zsyscall_linux.go | 10 + .../x/sys/unix/zsysnum_linux_386.go | 4 + .../x/sys/unix/zsysnum_linux_amd64.go | 3 + .../x/sys/unix/zsysnum_linux_arm.go | 4 + .../x/sys/unix/zsysnum_linux_arm64.go | 4 + .../x/sys/unix/zsysnum_linux_loong64.go | 4 + .../x/sys/unix/zsysnum_linux_mips.go | 4 + .../x/sys/unix/zsysnum_linux_mips64.go | 4 + .../x/sys/unix/zsysnum_linux_mips64le.go | 4 + .../x/sys/unix/zsysnum_linux_mipsle.go | 4 + .../x/sys/unix/zsysnum_linux_ppc.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 4 + .../x/sys/unix/zsysnum_linux_riscv64.go | 4 + .../x/sys/unix/zsysnum_linux_s390x.go | 4 + .../x/sys/unix/zsysnum_linux_sparc64.go | 4 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 185 +++-- .../golang.org/x/sys/windows/env_windows.go | 17 +- .../x/sys/windows/syscall_windows.go | 3 +- .../googleapis/api/annotations/client.pb.go | 139 ++-- .../grpc_binarylog_v1/binarylog.pb.go | 4 +- vendor/google.golang.org/grpc/clientconn.go | 2 + .../grpc/encoding/proto/proto.go | 24 +- .../grpc/health/grpc_health_v1/health.pb.go | 4 +- .../health/grpc_health_v1/health_grpc.pb.go | 2 +- .../grpc/internal/binarylog/method_logger.go | 9 +- .../grpc/internal/binarylog/sink.go | 2 +- .../grpc/internal/grpcrand/grpcrand.go | 5 + .../grpc/internal/grpcrand/grpcrand_go1.21.go | 73 ++ .../grpc/internal/pretty/pretty.go | 7 +- .../grpc/internal/status/status.go | 15 +- .../grpc/internal/transport/controlbuf.go | 5 +- .../grpc/internal/transport/handler_server.go | 2 +- .../grpc/internal/transport/http2_client.go | 8 +- .../grpc/internal/transport/http2_server.go | 29 +- .../grpc/internal/transport/transport.go | 9 +- .../grpc/resolver/resolver.go | 3 + .../grpc/resolver_wrapper.go | 1 + vendor/google.golang.org/grpc/rpc_util.go | 69 +- vendor/google.golang.org/grpc/server.go | 21 +- vendor/google.golang.org/grpc/stream.go | 5 +- vendor/google.golang.org/grpc/trace.go | 26 +- .../google.golang.org/grpc/trace_notrace.go | 52 ++ .../google.golang.org/grpc/trace_withtrace.go | 39 + vendor/google.golang.org/grpc/version.go | 2 +- vendor/google.golang.org/grpc/vet.sh | 2 +- .../protobuf/protoadapt/convert.go | 31 + vendor/k8s.io/klog/v2/.golangci.yaml | 6 + .../k8s.io/klog/v2/internal/buffer/buffer.go | 12 +- vendor/k8s.io/klog/v2/internal/clock/clock.go | 21 +- .../klog/v2/internal/serialize/keyvalues.go | 71 +- .../internal/serialize/keyvalues_no_slog.go | 97 +++ .../v2/internal/serialize/keyvalues_slog.go | 155 ++++ .../internal/sloghandler/sloghandler_slog.go | 96 +++ vendor/k8s.io/klog/v2/k8s_references_slog.go | 39 + vendor/k8s.io/klog/v2/klog.go | 66 +- vendor/k8s.io/klog/v2/klog_file.go | 4 +- vendor/k8s.io/klog/v2/klogr.go | 46 +- vendor/k8s.io/klog/v2/klogr_slog.go | 96 +++ vendor/modules.txt | 58 +- 285 files changed, 18855 insertions(+), 2676 deletions(-) delete mode 100644 csi/crypto/luks.go delete mode 100644 util/os.go delete mode 100644 util/os_test.go create mode 100644 vendor/github.com/go-logr/logr/SECURITY.md create mode 100644 vendor/github.com/go-logr/logr/slogr/sloghandler.go create mode 100644 vendor/github.com/go-logr/logr/slogr/slogr.go create mode 100644 vendor/github.com/go-logr/logr/slogr/slogsink.go create mode 100644 vendor/github.com/go-ole/go-ole/.travis.yml create mode 100644 vendor/github.com/go-ole/go-ole/ChangeLog.md create mode 100644 vendor/github.com/go-ole/go-ole/LICENSE create mode 100644 vendor/github.com/go-ole/go-ole/README.md create mode 100644 vendor/github.com/go-ole/go-ole/appveyor.yml create mode 100644 vendor/github.com/go-ole/go-ole/com.go create mode 100644 vendor/github.com/go-ole/go-ole/com_func.go create mode 100644 vendor/github.com/go-ole/go-ole/connect.go create mode 100644 vendor/github.com/go-ole/go-ole/constants.go create mode 100644 vendor/github.com/go-ole/go-ole/error.go create mode 100644 vendor/github.com/go-ole/go-ole/error_func.go create mode 100644 vendor/github.com/go-ole/go-ole/error_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/guid.go create mode 100644 vendor/github.com/go-ole/go-ole/iconnectionpoint.go create mode 100644 vendor/github.com/go-ole/go-ole/iconnectionpoint_func.go create mode 100644 vendor/github.com/go-ole/go-ole/iconnectionpoint_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/iconnectionpointcontainer.go create mode 100644 vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_func.go create mode 100644 vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/idispatch.go create mode 100644 vendor/github.com/go-ole/go-ole/idispatch_func.go create mode 100644 vendor/github.com/go-ole/go-ole/idispatch_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/ienumvariant.go create mode 100644 vendor/github.com/go-ole/go-ole/ienumvariant_func.go create mode 100644 vendor/github.com/go-ole/go-ole/ienumvariant_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/iinspectable.go create mode 100644 vendor/github.com/go-ole/go-ole/iinspectable_func.go create mode 100644 vendor/github.com/go-ole/go-ole/iinspectable_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/iprovideclassinfo.go create mode 100644 vendor/github.com/go-ole/go-ole/iprovideclassinfo_func.go create mode 100644 vendor/github.com/go-ole/go-ole/iprovideclassinfo_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/itypeinfo.go create mode 100644 vendor/github.com/go-ole/go-ole/itypeinfo_func.go create mode 100644 vendor/github.com/go-ole/go-ole/itypeinfo_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/iunknown.go create mode 100644 vendor/github.com/go-ole/go-ole/iunknown_func.go create mode 100644 vendor/github.com/go-ole/go-ole/iunknown_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/ole.go create mode 100644 vendor/github.com/go-ole/go-ole/oleutil/connection.go create mode 100644 vendor/github.com/go-ole/go-ole/oleutil/connection_func.go create mode 100644 vendor/github.com/go-ole/go-ole/oleutil/connection_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/oleutil/go-get.go create mode 100644 vendor/github.com/go-ole/go-ole/oleutil/oleutil.go create mode 100644 vendor/github.com/go-ole/go-ole/safearray.go create mode 100644 vendor/github.com/go-ole/go-ole/safearray_func.go create mode 100644 vendor/github.com/go-ole/go-ole/safearray_windows.go create mode 100644 vendor/github.com/go-ole/go-ole/safearrayconversion.go create mode 100644 vendor/github.com/go-ole/go-ole/safearrayslices.go create mode 100644 vendor/github.com/go-ole/go-ole/utility.go create mode 100644 vendor/github.com/go-ole/go-ole/variables.go create mode 100644 vendor/github.com/go-ole/go-ole/variant.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_386.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_amd64.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_arm.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_arm64.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_date_386.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_date_amd64.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_date_arm.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_date_arm64.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_ppc64le.go create mode 100644 vendor/github.com/go-ole/go-ole/variant_s390x.go create mode 100644 vendor/github.com/go-ole/go-ole/vt_string.go create mode 100644 vendor/github.com/go-ole/go-ole/winrt.go create mode 100644 vendor/github.com/go-ole/go-ole/winrt_doc.go delete mode 100644 vendor/github.com/golang/protobuf/jsonpb/decode.go delete mode 100644 vendor/github.com/golang/protobuf/jsonpb/encode.go delete mode 100644 vendor/github.com/golang/protobuf/jsonpb/json.go create mode 100644 vendor/github.com/longhorn/go-common-libs/LICENSE create mode 100644 vendor/github.com/longhorn/go-common-libs/exec/exec.go create mode 100644 vendor/github.com/longhorn/go-common-libs/io/file.go create mode 100644 vendor/github.com/longhorn/go-common-libs/ns/crypto.go create mode 100644 vendor/github.com/longhorn/go-common-libs/ns/executor.go create mode 100644 vendor/github.com/longhorn/go-common-libs/ns/file.go create mode 100644 vendor/github.com/longhorn/go-common-libs/ns/filelock.go create mode 100644 vendor/github.com/longhorn/go-common-libs/ns/joiner.go create mode 100644 vendor/github.com/longhorn/go-common-libs/ns/misc.go create mode 100644 vendor/github.com/longhorn/go-common-libs/ns/sys.go create mode 100644 vendor/github.com/longhorn/go-common-libs/proc/proc.go create mode 100644 vendor/github.com/longhorn/go-common-libs/sync/filelock.go create mode 100644 vendor/github.com/longhorn/go-common-libs/sys/sys.go create mode 100644 vendor/github.com/longhorn/go-common-libs/test/fake/file.go create mode 100644 vendor/github.com/longhorn/go-common-libs/test/fake/namespace.go create mode 100644 vendor/github.com/longhorn/go-common-libs/test/fake/system.go create mode 100644 vendor/github.com/longhorn/go-common-libs/types/crypto.go create mode 100644 vendor/github.com/longhorn/go-common-libs/types/exec.go create mode 100644 vendor/github.com/longhorn/go-common-libs/types/file.go create mode 100644 vendor/github.com/longhorn/go-common-libs/types/misc.go create mode 100644 vendor/github.com/longhorn/go-common-libs/types/namespace.go create mode 100644 vendor/github.com/longhorn/go-common-libs/types/proc.go create mode 100644 vendor/github.com/longhorn/go-common-libs/types/sys.go create mode 100644 vendor/github.com/longhorn/go-common-libs/utils/grpc.go create mode 100644 vendor/github.com/longhorn/go-common-libs/utils/longhorn_naming.go create mode 100644 vendor/github.com/longhorn/go-common-libs/utils/misc.go create mode 100644 vendor/github.com/longhorn/go-common-libs/utils/mount.go delete mode 100644 vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/luks.go create mode 100644 vendor/github.com/power-devops/perfstat/LICENSE create mode 100644 vendor/github.com/power-devops/perfstat/c_helpers.c create mode 100644 vendor/github.com/power-devops/perfstat/c_helpers.h create mode 100644 vendor/github.com/power-devops/perfstat/config.go create mode 100644 vendor/github.com/power-devops/perfstat/cpustat.go create mode 100644 vendor/github.com/power-devops/perfstat/diskstat.go create mode 100644 vendor/github.com/power-devops/perfstat/doc.go create mode 100644 vendor/github.com/power-devops/perfstat/fsstat.go create mode 100644 vendor/github.com/power-devops/perfstat/helpers.go create mode 100644 vendor/github.com/power-devops/perfstat/lparstat.go create mode 100644 vendor/github.com/power-devops/perfstat/lvmstat.go create mode 100644 vendor/github.com/power-devops/perfstat/memstat.go create mode 100644 vendor/github.com/power-devops/perfstat/netstat.go create mode 100644 vendor/github.com/power-devops/perfstat/procstat.go create mode 100644 vendor/github.com/power-devops/perfstat/sysconf.go create mode 100644 vendor/github.com/power-devops/perfstat/systemcfg.go create mode 100644 vendor/github.com/power-devops/perfstat/types_cpu.go create mode 100644 vendor/github.com/power-devops/perfstat/types_disk.go create mode 100644 vendor/github.com/power-devops/perfstat/types_fs.go create mode 100644 vendor/github.com/power-devops/perfstat/types_lpar.go create mode 100644 vendor/github.com/power-devops/perfstat/types_lvm.go create mode 100644 vendor/github.com/power-devops/perfstat/types_memory.go create mode 100644 vendor/github.com/power-devops/perfstat/types_network.go create mode 100644 vendor/github.com/power-devops/perfstat/types_process.go create mode 100644 vendor/github.com/power-devops/perfstat/uptime.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/LICENSE create mode 100644 vendor/github.com/shirou/gopsutil/v3/common/env.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_aix.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_cgo.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_nocgo.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_cgo.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_nocgo.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_fallback.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_386.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_linux.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_386.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_amd64.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_riscv64.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_solaris.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_unix.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/disk_windows.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.c create mode 100644 vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.h create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_darwin.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_freebsd.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_netbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_unix.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/endian.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go create mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go create mode 100644 vendor/github.com/yusufpapurcu/wmi/LICENSE create mode 100644 vendor/github.com/yusufpapurcu/wmi/README.md create mode 100644 vendor/github.com/yusufpapurcu/wmi/swbemservices.go create mode 100644 vendor/github.com/yusufpapurcu/wmi/wmi.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go create mode 100644 vendor/google.golang.org/grpc/trace_notrace.go create mode 100644 vendor/google.golang.org/grpc/trace_withtrace.go create mode 100644 vendor/google.golang.org/protobuf/protoadapt/convert.go create mode 100644 vendor/k8s.io/klog/v2/.golangci.yaml create mode 100644 vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go create mode 100644 vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go create mode 100644 vendor/k8s.io/klog/v2/internal/sloghandler/sloghandler_slog.go create mode 100644 vendor/k8s.io/klog/v2/k8s_references_slog.go create mode 100644 vendor/k8s.io/klog/v2/klogr_slog.go diff --git a/app/daemon.go b/app/daemon.go index d2621c90f6..fde68778ae 100644 --- a/app/daemon.go +++ b/app/daemon.go @@ -16,6 +16,9 @@ import ( iscsiutil "github.com/longhorn/go-iscsi-helper/util" + lhns "github.com/longhorn/go-common-libs/ns" + lhtypes "github.com/longhorn/go-common-libs/types" + "github.com/longhorn/longhorn-manager/api" "github.com/longhorn/longhorn-manager/controller" "github.com/longhorn/longhorn-manager/datastore" @@ -237,15 +240,13 @@ func startManager(c *cli.Context) error { } func environmentCheck() error { - initiatorNSPath := iscsiutil.GetHostNamespacePath(util.HostProcPath) - namespace, err := iscsiutil.NewNamespaceExecutor(initiatorNSPath) + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceNet} + nsexec, err := lhns.NewNamespaceExecutor(iscsiutil.ISCSIdProcess, lhtypes.HostProcDirectory, namespaces) if err != nil { return err } - if err := iscsi.CheckForInitiatorExistence(namespace); err != nil { - return err - } - return nil + + return iscsi.CheckForInitiatorExistence(nsexec) } func updateRegistrySecretName(m *manager.VolumeManager) error { diff --git a/controller/engine_controller.go b/controller/engine_controller.go index 1eab07a4eb..2c856519bf 100644 --- a/controller/engine_controller.go +++ b/controller/engine_controller.go @@ -27,6 +27,8 @@ import ( clientset "k8s.io/client-go/kubernetes" v1core "k8s.io/client-go/kubernetes/typed/core/v1" + lhexec "github.com/longhorn/go-common-libs/exec" + lhtypes "github.com/longhorn/go-common-libs/types" etypes "github.com/longhorn/longhorn-engine/pkg/types" imapi "github.com/longhorn/longhorn-instance-manager/pkg/api" imclient "github.com/longhorn/longhorn-instance-manager/pkg/client" @@ -570,7 +572,9 @@ func (ec *EngineController) DeleteInstance(obj interface{}) (err error) { url := imutil.GetURL(im.Status.IP, engineapi.InstanceManagerProcessManagerServiceDefaultPort) args := []string{"--url", url, "engine", "delete", "--name", e.Name} - _, err = util.ExecuteWithoutTimeout([]string{}, engineapi.GetDeprecatedInstanceManagerBinary(e.Status.CurrentImage), args...) + execute := lhexec.NewExecutor().Execute + deprecatedIMBinary := engineapi.GetDeprecatedInstanceManagerBinary(e.Status.CurrentImage) + _, err = execute([]string{}, deprecatedIMBinary, args, lhtypes.ExecuteNoTimeout) if err != nil && !types.ErrorIsNotFound(err) { return err } diff --git a/controller/monitor/disk_monitor.go b/controller/monitor/disk_monitor.go index 267e50d18b..5e04c0226a 100644 --- a/controller/monitor/disk_monitor.go +++ b/controller/monitor/disk_monitor.go @@ -14,6 +14,8 @@ import ( "k8s.io/apimachinery/pkg/util/wait" + lhtypes "github.com/longhorn/go-common-libs/types" + "github.com/longhorn/longhorn-manager/datastore" "github.com/longhorn/longhorn-manager/engineapi" "github.com/longhorn/longhorn-manager/types" @@ -48,13 +50,13 @@ type NodeMonitor struct { type CollectedDiskInfo struct { Path string NodeOrDiskEvicted bool - DiskStat *util.DiskStat + DiskStat *lhtypes.DiskStat DiskUUID string Condition *longhorn.Condition OrphanedReplicaDirectoryNames map[string]string } -type GetDiskStatHandler func(longhorn.DiskType, string, string, *engineapi.DiskService) (*util.DiskStat, error) +type GetDiskStatHandler func(longhorn.DiskType, string, string, *engineapi.DiskService) (*lhtypes.DiskStat, error) type GetDiskConfigHandler func(longhorn.DiskType, string, string, *engineapi.DiskService) (*util.DiskConfig, error) type GenerateDiskConfigHandler func(longhorn.DiskType, string, string, string, *engineapi.DiskService) (*util.DiskConfig, error) type GetReplicaInstanceNamesHandler func(longhorn.DiskType, *longhorn.Node, string, string, string, *engineapi.DiskService) (map[string]string, error) @@ -276,7 +278,7 @@ func canCollectDiskData(node *longhorn.Node, diskName, diskUUID, diskPath string types.GetCondition(node.Status.DiskStatus[diskName].Conditions, longhorn.DiskConditionTypeReady).Status == longhorn.ConditionStatusTrue } -func NewDiskInfo(path, diskUUID string, nodeOrDiskEvicted bool, stat *util.DiskStat, orphanedReplicaDirectoryNames map[string]string, errorReason, errorMessage string) *CollectedDiskInfo { +func NewDiskInfo(path, diskUUID string, nodeOrDiskEvicted bool, stat *lhtypes.DiskStat, orphanedReplicaDirectoryNames map[string]string, errorReason, errorMessage string) *CollectedDiskInfo { diskInfo := &CollectedDiskInfo{ Path: path, NodeOrDiskEvicted: nodeOrDiskEvicted, diff --git a/controller/monitor/disk_utils.go b/controller/monitor/disk_utils.go index a1fe4e00c8..6e8f181b5f 100644 --- a/controller/monitor/disk_utils.go +++ b/controller/monitor/disk_utils.go @@ -4,13 +4,15 @@ import ( "encoding/json" "fmt" "path/filepath" + "time" "github.com/pkg/errors" grpccodes "google.golang.org/grpc/codes" grpcstatus "google.golang.org/grpc/status" - iscsiutil "github.com/longhorn/go-iscsi-helper/util" + lhns "github.com/longhorn/go-common-libs/ns" + lhtypes "github.com/longhorn/go-common-libs/types" "github.com/longhorn/longhorn-manager/engineapi" "github.com/longhorn/longhorn-manager/util" @@ -23,10 +25,10 @@ const ( ) // GetDiskStat returns the disk stat of the given directory -func getDiskStat(diskType longhorn.DiskType, name, path string, client *engineapi.DiskService) (stat *util.DiskStat, err error) { +func getDiskStat(diskType longhorn.DiskType, name, path string, client *engineapi.DiskService) (stat *lhtypes.DiskStat, err error) { switch diskType { case longhorn.DiskTypeFilesystem: - return getFilesystemTypeDiskStat(path) + return lhns.GetDiskStat(path) case longhorn.DiskTypeBlock: return getBlockTypeDiskStat(client, name, path) default: @@ -34,11 +36,7 @@ func getDiskStat(diskType longhorn.DiskType, name, path string, client *engineap } } -func getFilesystemTypeDiskStat(path string) (stat *util.DiskStat, err error) { - return util.GetDiskStat(path) -} - -func getBlockTypeDiskStat(client *engineapi.DiskService, name, path string) (stat *util.DiskStat, err error) { +func getBlockTypeDiskStat(client *engineapi.DiskService, name, path string) (stat *lhtypes.DiskStat, err error) { if client == nil { return nil, errors.New("disk service client is nil") } @@ -47,7 +45,7 @@ func getBlockTypeDiskStat(client *engineapi.DiskService, name, path string) (sta if err != nil { return nil, err } - return &util.DiskStat{ + return &lhtypes.DiskStat{ DiskID: info.ID, Path: info.Path, Type: info.Type, @@ -72,20 +70,20 @@ func getDiskConfig(diskType longhorn.DiskType, name, path string, client *engine } func getFilesystemTypeDiskConfig(path string) (*util.DiskConfig, error) { - nsPath := iscsiutil.GetHostNamespacePath(util.HostProcPath) - nsExec, err := iscsiutil.NewNamespaceExecutor(nsPath) - if err != nil { - return nil, err - } - filePath := filepath.Join(path, util.DiskConfigFile) - output, err := nsExec.Execute("cat", []string{filePath}) + var err error + defer func() { + err = errors.Wrapf(err, "failed to get disk config for %v", path) + }() + + diskCfgFilePath := filepath.Join(path, util.DiskConfigFile) + output, err := lhns.ReadFileContent(diskCfgFilePath) if err != nil { - return nil, fmt.Errorf("cannot find config file %v on host: %v", filePath, err) + return nil, errors.Wrapf(err, "failed to read host disk config file %v", util.DiskConfigFile) } cfg := &util.DiskConfig{} if err := json.Unmarshal([]byte(output), cfg); err != nil { - return nil, fmt.Errorf("failed to unmarshal %v content %v on host: %v", filePath, output, err) + return nil, errors.Wrapf(err, "failed to unmarshal host %v content: %v", diskCfgFilePath, output) } return cfg, nil } @@ -120,6 +118,11 @@ func generateDiskConfig(diskType longhorn.DiskType, name, uuid, path string, cli } func generateFilesystemTypeDiskConfig(path string) (*util.DiskConfig, error) { + var err error + defer func() { + err = errors.Wrapf(err, "failed to generate disk config for %v", path) + }() + cfg := &util.DiskConfig{ DiskUUID: util.UUID(), } @@ -128,33 +131,29 @@ func generateFilesystemTypeDiskConfig(path string) (*util.DiskConfig, error) { return nil, fmt.Errorf("BUG: Cannot marshal %+v: %v", cfg, err) } - nsPath := iscsiutil.GetHostNamespacePath(util.HostProcPath) - nsExec, err := iscsiutil.NewNamespaceExecutor(nsPath) - if err != nil { - return nil, err - } - filePath := filepath.Join(path, util.DiskConfigFile) - if _, err := nsExec.Execute("ls", []string{filePath}); err == nil { - return nil, fmt.Errorf("disk cfg on %v exists, cannot override", filePath) + diskCfgFilePath := filepath.Join(path, util.DiskConfigFile) + if _, err := lhns.GetFileInfo(diskCfgFilePath); err == nil { + return nil, fmt.Errorf("disk cfg on %v exists, cannot override", diskCfgFilePath) } defer func() { if err != nil { - if derr := util.DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile(nsExec, path); derr != nil { + if derr := util.DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile(path); derr != nil { err = errors.Wrapf(err, "cleaning up disk config path %v failed with error: %v", path, derr) } - } }() - if _, err := nsExec.ExecuteWithStdin("dd", []string{"of=" + filePath}, string(encoded)); err != nil { - return nil, fmt.Errorf("cannot write to disk cfg on %v: %v", filePath, err) - } - if err := util.CreateDiskPathReplicaSubdirectory(path); err != nil { + if err := lhns.WriteFile(diskCfgFilePath, string(encoded)); err != nil { return nil, err } - if _, err := nsExec.Execute("sync", []string{filePath}); err != nil { - return nil, fmt.Errorf("cannot sync disk cfg on %v: %v", filePath, err) + + if _, err := lhns.CreateDirectory(filepath.Join(path, util.ReplicaDirectory), time.Now()); err != nil { + return nil, errors.Wrapf(err, "failed to create replica subdirectory %v", path) + } + + if err := lhns.SyncFile(diskCfgFilePath); err != nil { + return nil, err } return cfg, nil diff --git a/controller/monitor/fake_disk_monitor.go b/controller/monitor/fake_disk_monitor.go index 32371348e9..b4841b8eb5 100644 --- a/controller/monitor/fake_disk_monitor.go +++ b/controller/monitor/fake_disk_monitor.go @@ -7,6 +7,7 @@ import ( "github.com/sirupsen/logrus" + lhtypes "github.com/longhorn/go-common-libs/types" "github.com/longhorn/longhorn-manager/datastore" "github.com/longhorn/longhorn-manager/engineapi" "github.com/longhorn/longhorn-manager/util" @@ -49,10 +50,10 @@ func fakeGetReplicaDirectoryNames(diskType longhorn.DiskType, node *longhorn.Nod }, nil } -func fakeGetDiskStat(diskType longhorn.DiskType, name, directory string, client *engineapi.DiskService) (*util.DiskStat, error) { +func fakeGetDiskStat(diskType longhorn.DiskType, name, directory string, client *engineapi.DiskService) (*lhtypes.DiskStat, error) { switch diskType { case longhorn.DiskTypeFilesystem: - return &util.DiskStat{ + return &lhtypes.DiskStat{ DiskID: "fsid", Path: directory, Type: "ext4", @@ -64,7 +65,7 @@ func fakeGetDiskStat(diskType longhorn.DiskType, name, directory string, client StorageAvailable: 0, }, nil case longhorn.DiskTypeBlock: - return &util.DiskStat{ + return &lhtypes.DiskStat{ DiskID: "block", Path: directory, Type: "ext4", diff --git a/controller/orphan_controller.go b/controller/orphan_controller.go index 55740f862b..ad74291738 100644 --- a/controller/orphan_controller.go +++ b/controller/orphan_controller.go @@ -2,6 +2,7 @@ package controller import ( "fmt" + "path/filepath" "reflect" "strings" "time" @@ -21,10 +22,11 @@ import ( clientset "k8s.io/client-go/kubernetes" v1core "k8s.io/client-go/kubernetes/typed/core/v1" + lhns "github.com/longhorn/go-common-libs/ns" + "github.com/longhorn/longhorn-manager/datastore" "github.com/longhorn/longhorn-manager/engineapi" "github.com/longhorn/longhorn-manager/types" - "github.com/longhorn/longhorn-manager/util" longhorn "github.com/longhorn/longhorn-manager/k8s/pkg/apis/longhorn/v1beta2" ) @@ -315,7 +317,10 @@ func (oc *OrphanController) deleteOrphanedReplica(orphan *longhorn.Orphan) error switch longhorn.DiskType(diskType) { case longhorn.DiskTypeFilesystem: - return util.DeleteReplicaDirectory(orphan.Spec.Parameters[longhorn.OrphanDiskPath], orphan.Spec.Parameters[longhorn.OrphanDataName]) + diskPath := orphan.Spec.Parameters[longhorn.OrphanDiskPath] + replicaDirectoryName := orphan.Spec.Parameters[longhorn.OrphanDataName] + err := lhns.DeletePath(filepath.Join(diskPath, "replicas", replicaDirectoryName)) + return errors.Wrapf(err, "failed to delete orphan replica directory %v in disk %v", replicaDirectoryName, diskPath) case longhorn.DiskTypeBlock: return oc.DeleteSpdkReplicaInstance(orphan.Spec.Parameters[longhorn.OrphanDiskName], orphan.Spec.Parameters[longhorn.OrphanDiskUUID], orphan.Spec.Parameters[longhorn.OrphanDataName]) default: diff --git a/controller/replica_controller.go b/controller/replica_controller.go index 1f231fd3f2..c1182fec0c 100644 --- a/controller/replica_controller.go +++ b/controller/replica_controller.go @@ -28,11 +28,12 @@ import ( imapi "github.com/longhorn/longhorn-instance-manager/pkg/api" + lhns "github.com/longhorn/go-common-libs/ns" + "github.com/longhorn/longhorn-manager/constant" "github.com/longhorn/longhorn-manager/datastore" "github.com/longhorn/longhorn-manager/engineapi" "github.com/longhorn/longhorn-manager/types" - "github.com/longhorn/longhorn-manager/util" longhorn "github.com/longhorn/longhorn-manager/k8s/pkg/apis/longhorn/v1beta2" ) @@ -257,7 +258,7 @@ func (rc *ReplicaController) syncReplica(key string) (err error) { return fmt.Errorf("%v doesn't look like a replica data path", dataPath) } log.Info("Cleaning up replica") - if err := util.RemoveHostDirectoryContent(dataPath); err != nil { + if err := lhns.DeleteDirectory(dataPath); err != nil { return errors.Wrapf(err, "cannot cleanup after replica %v at %v", replica.Name, dataPath) } } else { diff --git a/controller/setting_controller.go b/controller/setting_controller.go index 2801d87636..2b0c95c950 100644 --- a/controller/setting_controller.go +++ b/controller/setting_controller.go @@ -33,6 +33,8 @@ import ( "k8s.io/client-go/tools/record" "k8s.io/kubernetes/pkg/controller" + lhns "github.com/longhorn/go-common-libs/ns" + "github.com/longhorn/longhorn-manager/constant" "github.com/longhorn/longhorn-manager/datastore" "github.com/longhorn/longhorn-manager/types" @@ -1678,7 +1680,7 @@ func (info *ClusterInfo) collectNodeScope() { } func (info *ClusterInfo) collectHostKernelRelease() error { - kernelRelease, err := util.GetHostKernelRelease() + kernelRelease, err := lhns.GetKernelRelease() if err == nil { info.structFields.tags.Append(ClusterInfoHostKernelRelease, kernelRelease) } @@ -1687,7 +1689,7 @@ func (info *ClusterInfo) collectHostKernelRelease() error { func (info *ClusterInfo) collectHostOSDistro() (err error) { if info.osDistro == "" { - info.osDistro, err = util.GetHostOSDistro() + info.osDistro, err = lhns.GetOSDistro() if err != nil { return err } diff --git a/csi/crypto/crypto.go b/csi/crypto/crypto.go index 45a42bdf9b..3c491469ad 100644 --- a/csi/crypto/crypto.go +++ b/csi/crypto/crypto.go @@ -7,6 +7,9 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" + + lhns "github.com/longhorn/go-common-libs/ns" + lhtypes "github.com/longhorn/go-common-libs/types" ) const ( @@ -66,8 +69,20 @@ func VolumeMapper(volume string) string { // EncryptVolume encrypts provided device with LUKS. func EncryptVolume(devicePath, passphrase string, cryptoParams *EncryptParams) error { + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.ProcDirectory, namespaces) + if err != nil { + return err + } + logrus.Infof("Encrypting device %s with LUKS", devicePath) - if _, err := luksFormat(devicePath, passphrase, cryptoParams); err != nil { + if _, err := nsexec.LuksFormat( + devicePath, passphrase, + cryptoParams.GetKeyCipher(), + cryptoParams.GetKeyHash(), + cryptoParams.GetKeySize(), + cryptoParams.GetPBKDF(), + lhtypes.LuksTimeout); err != nil { return errors.Wrapf(err, "failed to encrypt device %s with LUKS", devicePath) } return nil @@ -80,8 +95,14 @@ func OpenVolume(volume, devicePath, passphrase string) error { return nil } + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.ProcDirectory, namespaces) + if err != nil { + return err + } + logrus.Infof("Opening device %s with LUKS on %s", devicePath, volume) - _, err := luksOpen(volume, devicePath, passphrase) + _, err = nsexec.LuksOpen(volume, devicePath, passphrase, lhtypes.LuksTimeout) if err != nil { logrus.WithError(err).Warnf("Failed to open LUKS device %s", devicePath) } @@ -90,8 +111,14 @@ func OpenVolume(volume, devicePath, passphrase string) error { // CloseVolume closes encrypted volume so it can be detached. func CloseVolume(volume string) error { + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.ProcDirectory, namespaces) + if err != nil { + return err + } + logrus.Infof("Closing LUKS device %s", volume) - _, err := luksClose(volume) + _, err = nsexec.LuksClose(volume, lhtypes.LuksTimeout) return err } @@ -102,7 +129,13 @@ func ResizeEncryptoDevice(volume, passphrase string) error { return fmt.Errorf("volume %v encrypto device is closed for resizing", volume) } - _, err := luksResize(volume, passphrase) + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.ProcDirectory, namespaces) + if err != nil { + return err + } + + _, err = nsexec.LuksResize(volume, passphrase, lhtypes.LuksTimeout) return err } @@ -119,20 +152,30 @@ func DeviceEncryptionStatus(devicePath string) (mappedDevice, mapper string, err if !strings.HasPrefix(devicePath, mapperFilePathPrefix) { return devicePath, "", nil } + + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.ProcDirectory, namespaces) + if err != nil { + return devicePath, "", err + } + volume := strings.TrimPrefix(devicePath, mapperFilePathPrefix+"/") - stdout, err := luksStatus(volume) + stdout, err := nsexec.LuksStatus(volume, lhtypes.LuksTimeout) if err != nil { logrus.WithError(err).Warnf("Device %s is not an active LUKS device", devicePath) return devicePath, "", nil } + lines := strings.Split(string(stdout), "\n") if len(lines) < 1 { return "", "", fmt.Errorf("device encryption status returned no stdout for %s", devicePath) } + if !strings.Contains(lines[0], " is active") { // Implies this is not a LUKS device return devicePath, "", nil } + for i := 1; i < len(lines); i++ { kv := strings.SplitN(strings.TrimSpace(lines[i]), ":", 2) if len(kv) < 1 { diff --git a/csi/crypto/luks.go b/csi/crypto/luks.go deleted file mode 100644 index 34fa01aa62..0000000000 --- a/csi/crypto/luks.go +++ /dev/null @@ -1,83 +0,0 @@ -package crypto - -import ( - "bytes" - "context" - "os/exec" - "path/filepath" - "strings" - "time" - - iscsiutil "github.com/longhorn/go-iscsi-helper/util" - "github.com/pkg/errors" -) - -const hostProcPath = "/proc" // we use hostPID for the csi plugin -const luksTimeout = time.Minute - -func luksOpen(volume, devicePath, passphrase string) (stdout string, err error) { - return cryptSetupWithPassphrase(passphrase, - "luksOpen", devicePath, volume, "-d", "/dev/stdin") -} - -func luksClose(volume string) (stdout string, err error) { - return cryptSetup("luksClose", volume) -} - -func luksFormat(devicePath, passphrase string, cryptoParams *EncryptParams) (stdout string, err error) { - return cryptSetupWithPassphrase(passphrase, - "-q", "luksFormat", "--type", "luks2", "--cipher", cryptoParams.GetKeyCipher(), "--hash", cryptoParams.GetKeyHash(), "--key-size", cryptoParams.GetKeySize(), "--pbkdf", cryptoParams.GetPBKDF(), - devicePath, "-d", "/dev/stdin") -} - -func luksResize(volume, passphrase string) (stdout string, err error) { - return cryptSetupWithPassphrase(passphrase, "resize", volume) -} - -func luksStatus(volume string) (stdout string, err error) { - return cryptSetup("status", volume) -} - -func cryptSetup(args ...string) (stdout string, err error) { - return cryptSetupWithPassphrase("", args...) -} - -// cryptSetupWithPassphrase runs cryptsetup via nsenter inside of the host namespaces -// cryptsetup returns 0 on success and a non-zero value on error. -// 1 wrong parameters, 2 no permission (bad passphrase), -// 3 out of memory, 4 wrong device specified, -// 5 device already exists or device is busy. -func cryptSetupWithPassphrase(passphrase string, args ...string) (stdout string, err error) { - // NOTE: cryptsetup needs to be run in the host IPC/MNT - // if you only use MNT the binary will not return but still do the appropriate action. - ns := iscsiutil.GetHostNamespacePath(hostProcPath) - nsArgs := prepareCommandArgs(ns, "cryptsetup", args) - ctx, cancel := context.WithTimeout(context.TODO(), luksTimeout) - defer cancel() - cmd := exec.CommandContext(ctx, "nsenter", nsArgs...) - - stdoutBuf := &bytes.Buffer{} - stderrBuf := &bytes.Buffer{} - cmd.Stdout = stdoutBuf - cmd.Stderr = stderrBuf - - if len(passphrase) > 0 { - cmd.Stdin = strings.NewReader(passphrase) - } - - if err := cmd.Run(); err != nil { - return stdoutBuf.String(), errors.Wrapf(err, "failed to run cryptsetup, args: %v, stdout: %v, stderr: %v", - args, stdoutBuf.String(), stderrBuf.String()) - } - - return stdoutBuf.String(), nil -} - -func prepareCommandArgs(ns, cmd string, args []string) []string { - cmdArgs := []string{ - "--mount=" + filepath.Join(ns, "mnt"), - "--ipc=" + filepath.Join(ns, "ipc"), - cmd, - } - return append(cmdArgs, args...) -} diff --git a/engineapi/backups.go b/engineapi/backups.go index 73cddef180..4883fd7003 100644 --- a/engineapi/backups.go +++ b/engineapi/backups.go @@ -13,6 +13,8 @@ import ( "github.com/longhorn/backupstore" btypes "github.com/longhorn/backupstore/types" + lhexec "github.com/longhorn/go-common-libs/exec" + lhtypes "github.com/longhorn/go-common-libs/types" etypes "github.com/longhorn/longhorn-engine/pkg/types" "github.com/longhorn/longhorn-manager/datastore" @@ -128,7 +130,7 @@ func (btc *BackupTargetClient) ExecuteEngineBinary(args ...string) (string, erro if err != nil { return "", err } - return util.Execute(envs, btc.LonghornEngineBinary(), args...) + return lhexec.NewExecutor().Execute(envs, btc.LonghornEngineBinary(), args, lhtypes.ExecuteDefaultTimeout) } func (btc *BackupTargetClient) ExecuteEngineBinaryWithTimeout(timeout time.Duration, args ...string) (string, error) { @@ -136,7 +138,7 @@ func (btc *BackupTargetClient) ExecuteEngineBinaryWithTimeout(timeout time.Durat if err != nil { return "", err } - return util.ExecuteWithTimeout(timeout, envs, btc.LonghornEngineBinary(), args...) + return lhexec.NewExecutor().Execute(envs, btc.LonghornEngineBinary(), args, timeout) } func (btc *BackupTargetClient) ExecuteEngineBinaryWithoutTimeout(args ...string) (string, error) { @@ -144,7 +146,7 @@ func (btc *BackupTargetClient) ExecuteEngineBinaryWithoutTimeout(args ...string) if err != nil { return "", err } - return util.ExecuteWithoutTimeout(envs, btc.LonghornEngineBinary(), args...) + return lhexec.NewExecutor().Execute(envs, btc.LonghornEngineBinary(), args, lhtypes.ExecuteNoTimeout) } // parseBackupVolumeNamesList parses a list of backup volume names into a sorted string slice diff --git a/engineapi/engine.go b/engineapi/engine.go index 1a961dd443..77a16e157f 100644 --- a/engineapi/engine.go +++ b/engineapi/engine.go @@ -10,10 +10,11 @@ import ( "github.com/pkg/errors" + lhexec "github.com/longhorn/go-common-libs/exec" + lhtypes "github.com/longhorn/go-common-libs/types" imutil "github.com/longhorn/longhorn-instance-manager/pkg/util" "github.com/longhorn/longhorn-manager/types" - "github.com/longhorn/longhorn-manager/util" longhorn "github.com/longhorn/longhorn-manager/k8s/pkg/apis/longhorn/v1beta2" ) @@ -70,7 +71,7 @@ func (e *EngineBinary) ExecuteEngineBinary(args ...string) (string, error) { if err != nil { return "", err } - return util.Execute([]string{}, e.LonghornEngineBinary(), args...) + return lhexec.NewExecutor().Execute([]string{}, e.LonghornEngineBinary(), args, lhtypes.ExecuteDefaultTimeout) } func (e *EngineBinary) ExecuteEngineBinaryWithTimeout(timeout time.Duration, args ...string) (string, error) { @@ -78,7 +79,7 @@ func (e *EngineBinary) ExecuteEngineBinaryWithTimeout(timeout time.Duration, arg if err != nil { return "", err } - return util.ExecuteWithTimeout(timeout, []string{}, e.LonghornEngineBinary(), args...) + return lhexec.NewExecutor().Execute([]string{}, e.LonghornEngineBinary(), args, timeout) } func (e *EngineBinary) ExecuteEngineBinaryWithoutTimeout(envs []string, args ...string) (string, error) { @@ -86,7 +87,7 @@ func (e *EngineBinary) ExecuteEngineBinaryWithoutTimeout(envs []string, args ... if err != nil { return "", err } - return util.ExecuteWithoutTimeout(envs, e.LonghornEngineBinary(), args...) + return lhexec.NewExecutor().Execute(envs, e.LonghornEngineBinary(), args, lhtypes.ExecuteNoTimeout) } func parseReplica(s string) (*Replica, error) { @@ -206,7 +207,7 @@ func (e *EngineBinary) VersionGet(engine *longhorn.Engine, clientOnly bool) (*En } else { cmdline = append([]string{"--url", e.cURL}, cmdline...) } - output, err := util.Execute([]string{}, e.LonghornEngineBinary(), cmdline...) + output, err := lhexec.NewExecutor().Execute([]string{}, e.LonghornEngineBinary(), cmdline, lhtypes.ExecuteDefaultTimeout) if err != nil { return nil, errors.Wrapf(err, "cannot get volume version") } diff --git a/go.mod b/go.mod index f500134e1a..38f47a3465 100644 --- a/go.mod +++ b/go.mod @@ -46,11 +46,12 @@ require ( github.com/kubernetes-csi/csi-lib-utils v0.6.1 github.com/longhorn/backing-image-manager v1.5.4 github.com/longhorn/backupstore v0.0.0-20240219094812-3a87ee02df77 - github.com/longhorn/go-iscsi-helper v0.0.0-20231113050545-9df1e6b605c7 + github.com/longhorn/go-common-libs v0.0.0-20240319112414-b75404dc7fbc + github.com/longhorn/go-iscsi-helper v0.0.0-20240308033847-bc3aab599425 github.com/longhorn/go-spdk-helper v0.0.0-20231113055029-9acddd184246 - github.com/longhorn/longhorn-engine v1.5.4 - github.com/longhorn/longhorn-instance-manager v1.5.4 - github.com/longhorn/longhorn-share-manager v1.5.4 + github.com/longhorn/longhorn-engine v1.5.5-0.20240319113652-9cdc0f5750a7 + github.com/longhorn/longhorn-instance-manager v1.5.5-0.20240326065406-8d925c0e7e1e + github.com/longhorn/longhorn-share-manager v1.5.5-0.20240319114127-58303a9ff61f github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 github.com/rancher/dynamiclistener v0.3.6 @@ -62,9 +63,9 @@ require ( github.com/urfave/cli v1.22.14 golang.org/x/mod v0.10.0 golang.org/x/net v0.20.0 - golang.org/x/sys v0.16.0 + golang.org/x/sys v0.18.0 golang.org/x/time v0.3.0 - google.golang.org/grpc v1.61.0 + google.golang.org/grpc v1.62.1 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.28.6 @@ -74,18 +75,22 @@ require ( k8s.io/client-go v0.28.6 k8s.io/kubernetes v1.28.2 k8s.io/metrics v0.28.2 - k8s.io/mount-utils v0.28.2 + k8s.io/mount-utils v0.29.3 k8s.io/utils v0.0.0-20240310230437-4693a0247e57 sigs.k8s.io/controller-runtime v0.10.1 ) require ( github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/shirou/gopsutil/v3 v3.24.2 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/tools v0.8.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect google.golang.org/protobuf v1.33.0 // indirect ) @@ -114,7 +119,7 @@ require ( github.com/gammazero/deque v0.2.1 // indirect github.com/gammazero/workerpool v1.1.3 // indirect github.com/go-co-op/gocron v1.18.0 - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -177,12 +182,12 @@ require ( go.uber.org/multierr v1.11.0 go.uber.org/zap v1.19.0 // indirect golang.org/x/crypto v0.18.0 // indirect - golang.org/x/oauth2 v0.14.0 // indirect - golang.org/x/sync v0.5.0 + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/sync v0.6.0 golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect + google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -192,7 +197,7 @@ require ( k8s.io/component-helpers v0.28.2 // indirect k8s.io/controller-manager v0.28.2 // indirect k8s.io/klog v1.0.0 // indirect - k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kms v0.28.2 // indirect k8s.io/kube-aggregator v0.25.4 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect diff --git a/go.sum b/go.sum index ed9ad83155..3c909d1a98 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34h cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= @@ -172,8 +172,8 @@ cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvj cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= -cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -602,7 +602,6 @@ git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3p github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= @@ -686,6 +685,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/container-storage-interface/spec v1.8.0 h1:D0vhF3PLIZwlwZEf2eNbpujGCNwspwTYf2idJRJx4xI= github.com/container-storage-interface/spec v1.8.0/go.mod h1:ROLik+GhPslwwWRNFF1KasPzroNARibH2rfz1rkg4H0= @@ -736,12 +737,13 @@ github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -782,13 +784,16 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v0.4.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= @@ -813,8 +818,9 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -848,7 +854,6 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= @@ -879,7 +884,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -911,7 +915,6 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -936,17 +939,11 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= @@ -1037,56 +1034,25 @@ github.com/kubernetes-csi/csi-lib-utils v0.6.1 h1:+AZ58SRSRWh2vmMoWAAGcv7x6fIyBM github.com/kubernetes-csi/csi-lib-utils v0.6.1/go.mod h1:GVmlUmxZ+SUjVLXicRFjqWUUvWez0g0Y78zNV9t7KfQ= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= -github.com/longhorn/backing-image-manager v1.4.0-rc1.0.20230521151917-38ff27cc2cbb h1:y59M4Z8jvOowAwdXcATyHjG31ZbaMJvjIPY+SpVmeII= -github.com/longhorn/backing-image-manager v1.4.0-rc1.0.20230521151917-38ff27cc2cbb/go.mod h1:yhfIPKYbnFpRmrJOz0biNthyoyBpN4SrUk8ZQNMcW1o= -github.com/longhorn/backing-image-manager v1.5.4-rc2 h1:d3sGFahaME4t+kyBh0xrG4VbMxcLDuEl8GjZXlRNsBE= -github.com/longhorn/backing-image-manager v1.5.4-rc2/go.mod h1:U0FFqnzc+NHk4q+HqVaVFewlRS8xsx2MG1KlNJnREFA= -github.com/longhorn/backing-image-manager v1.5.4-rc3 h1:c6Kf66t3swCk+Dl2DuBrIb0DKGCwqDAgsZZDOvZiO9c= -github.com/longhorn/backing-image-manager v1.5.4-rc3/go.mod h1:U0FFqnzc+NHk4q+HqVaVFewlRS8xsx2MG1KlNJnREFA= -github.com/longhorn/backing-image-manager v1.5.4-rc4 h1:2TQs/VV451h0lAx0w5cb/xrHzMcENwhiNaCNbXbuKLk= -github.com/longhorn/backing-image-manager v1.5.4-rc4/go.mod h1:M28iC1bpVgefAt8E72ozeE9aSwxXcoXmmIClj5zC7bo= github.com/longhorn/backing-image-manager v1.5.4 h1:z5eQ3r39q3VyuCSNtX2S++2tPaorsnOopKf3cjjvNzE= github.com/longhorn/backing-image-manager v1.5.4/go.mod h1:M28iC1bpVgefAt8E72ozeE9aSwxXcoXmmIClj5zC7bo= -github.com/longhorn/backupstore v0.0.0-20231025000449-5316e8b5320d h1:WrjW6b0VmaapZWBKLSJTyZ7A5xzN0mciraLbPG9rExE= -github.com/longhorn/backupstore v0.0.0-20231025000449-5316e8b5320d/go.mod h1:wiEYTbvxEAIUxAAY1DmvMeuFuGqwWmJTzfVhZiBKlNo= -github.com/longhorn/backupstore v0.0.0-20231114103026-af339bb498d3 h1:z1+k7ANPYjYyq0FMljsM/0jXmS/tB0pPLi18RWBUQ9c= -github.com/longhorn/backupstore v0.0.0-20231114103026-af339bb498d3/go.mod h1:JzuHEmLyQPhGuxtKpJ2vCXPfGbylXJiBVg4KLVKsj9c= github.com/longhorn/backupstore v0.0.0-20240219094812-3a87ee02df77 h1:iJRq59kA22f9HIjFtY/lz5rKCorZJrrYXju70XoWdmE= github.com/longhorn/backupstore v0.0.0-20240219094812-3a87ee02df77/go.mod h1:4cbJWtlrD2cGTQxQLtdlPTYopiJiusXH7CpOBrn/s3k= -github.com/longhorn/go-iscsi-helper v0.0.0-20231113050545-9df1e6b605c7 h1:YOOhIENIfhVCOaD00oWFeothjP0UyItBScUmpwGg8TM= -github.com/longhorn/go-iscsi-helper v0.0.0-20231113050545-9df1e6b605c7/go.mod h1:xz30xMoSLdYxfUygCzM/s99CA8/LNrkcEULFWExhqz4= +github.com/longhorn/go-common-libs v0.0.0-20240319112414-b75404dc7fbc h1:Eh9Npc5yBcVD8E4zVQIGUtC62HcfqevrHjQ2kh7fJ/E= +github.com/longhorn/go-common-libs v0.0.0-20240319112414-b75404dc7fbc/go.mod h1:ESTw7LYBF+dB5VndQNKXKrD6B9s/hF94lotGKXLovlM= +github.com/longhorn/go-iscsi-helper v0.0.0-20240308033847-bc3aab599425 h1:koSD52H0VkzJAh3OIZCdgQ9mqoRXklkeuhqmuwQ1WzU= +github.com/longhorn/go-iscsi-helper v0.0.0-20240308033847-bc3aab599425/go.mod h1:2aM6KBix3Khd56I4rihOBOOPOm0/YvYMjtr1KNclQsI= github.com/longhorn/go-spdk-helper v0.0.0-20231113055029-9acddd184246 h1:Pry2QHJEqEy9jsRIaACmq/1Hre8N9wfE061+gQKspKg= github.com/longhorn/go-spdk-helper v0.0.0-20231113055029-9acddd184246/go.mod h1:PCawMRVllTJnjbIYIC8axRfEI7aEhhjbsoBS/Y/EUYQ= -github.com/longhorn/longhorn-engine v1.5.2-0.20230906182804-9475221d9535 h1:mfkKctSnweL36Y2gUxQoXDyfJ72CsAhwCgG4I2vhHMw= -github.com/longhorn/longhorn-engine v1.5.2-0.20230906182804-9475221d9535/go.mod h1:OOjKIyGpTxmZFWkn8N1G+H4pga0niuMgzrR/h5HUJNo= -github.com/longhorn/longhorn-engine v1.5.4-rc2 h1:s5TcKMKWMNV6nlzMVA689y3P0GJ3+I5iULyHTDMO7jY= -github.com/longhorn/longhorn-engine v1.5.4-rc2/go.mod h1:WKFaWED6hl+DMo8YQlz7HCsWMB3JDxjP0DKnSIfXP4E= -github.com/longhorn/longhorn-engine v1.5.4-rc3 h1:ffHLJlOyipEwIsJza9y/l80qEZUpvoXcp9yTq5keQIc= -github.com/longhorn/longhorn-engine v1.5.4-rc3/go.mod h1:WKFaWED6hl+DMo8YQlz7HCsWMB3JDxjP0DKnSIfXP4E= -github.com/longhorn/longhorn-engine v1.5.4-rc4 h1:7o0FWhKTP2c7reof+zWgXy1XzFtIVFKlp6kPHlECgIU= -github.com/longhorn/longhorn-engine v1.5.4-rc4/go.mod h1:uQyRRyIJunT8T7yNiTJrxGtHD9TB/W8LyYmoHNbTbaU= -github.com/longhorn/longhorn-engine v1.5.4 h1:Nnj8FueCrrIexjgFkG9+CaaZ4w9XV5DOlvGY9XzIZ1w= -github.com/longhorn/longhorn-engine v1.5.4/go.mod h1:uQyRRyIJunT8T7yNiTJrxGtHD9TB/W8LyYmoHNbTbaU= -github.com/longhorn/longhorn-instance-manager v1.5.4-rc2.0.20240220083528-fa10cc97578b h1:aqBNcYL9JVtkVeBKC90MB+aHbMx9pkT6BsO5iQlcYd0= -github.com/longhorn/longhorn-instance-manager v1.5.4-rc2.0.20240220083528-fa10cc97578b/go.mod h1:gkU0l28b5QDmUPiO2WL1IHwxkUyvW2dhpIN52FNlrww= -github.com/longhorn/longhorn-instance-manager v1.5.4-rc3 h1:XXUrIqI3GxoUpAe1cz5h8wkyg3+Iq3FClq6tOuBps74= -github.com/longhorn/longhorn-instance-manager v1.5.4-rc3/go.mod h1:gkU0l28b5QDmUPiO2WL1IHwxkUyvW2dhpIN52FNlrww= -github.com/longhorn/longhorn-instance-manager v1.5.4-rc4 h1:R6FT3lFEPOLx9Lrf37StGYEWwC8uW4WuQTSRHKSXB9E= -github.com/longhorn/longhorn-instance-manager v1.5.4-rc4/go.mod h1:gXA9BnQiP6m90JkwNBCwKLdKdXjt4WX4W+wsbV/GzpY= -github.com/longhorn/longhorn-instance-manager v1.5.4 h1:2br2sGE6ES77PN+UjT0uN5IW/r+anpddRQnplih1JCY= -github.com/longhorn/longhorn-instance-manager v1.5.4/go.mod h1:gXA9BnQiP6m90JkwNBCwKLdKdXjt4WX4W+wsbV/GzpY= -github.com/longhorn/longhorn-share-manager v1.5.3-rc1.0.20231115141215-5109d5939e17 h1:0aCMBoX4nTKpHBFD1lwcRaRc8oQcr6bqfFEIp9VpRYw= -github.com/longhorn/longhorn-share-manager v1.5.3-rc1.0.20231115141215-5109d5939e17/go.mod h1:2Ti49HwYOBt5O9aU3Eminw0aiu1e3S0qdn7yByI+C9Q= -github.com/longhorn/longhorn-share-manager v1.5.4-rc2 h1:1Bt1P+hRaPOGSxsG/gdUQj75C4Ge5fC9qMxccexQibI= -github.com/longhorn/longhorn-share-manager v1.5.4-rc2/go.mod h1:A/Z/YpW//hdULf+ZxelXQi8VEfAIIDRvEFvmv0xHSU0= -github.com/longhorn/longhorn-share-manager v1.5.4-rc3 h1:DdWYM4k/M2+rtcTe9EJhWy6cmH/IDrmyXgi1XxFSVQw= -github.com/longhorn/longhorn-share-manager v1.5.4-rc3/go.mod h1:A/Z/YpW//hdULf+ZxelXQi8VEfAIIDRvEFvmv0xHSU0= -github.com/longhorn/longhorn-share-manager v1.5.4-rc4 h1:p5iBA2NplRL/3L15F1JcXd3SSfMJkC1b0wAcE5tIVUs= -github.com/longhorn/longhorn-share-manager v1.5.4-rc4/go.mod h1:KPaMWVCgvu8CCJ0EQL7ZUGGpOLhPZ4+NCFR4MP8iaMI= -github.com/longhorn/longhorn-share-manager v1.5.4 h1:3aGERI/UQVFwThDScQqLQiCbVe1FW7VlWNQVDKbH3FE= -github.com/longhorn/longhorn-share-manager v1.5.4/go.mod h1:KPaMWVCgvu8CCJ0EQL7ZUGGpOLhPZ4+NCFR4MP8iaMI= +github.com/longhorn/longhorn-engine v1.5.5-0.20240319113652-9cdc0f5750a7 h1:s7jcIWVGGJyqsM/7XO742XIK3hWZQJwasR6eR9gs4Yg= +github.com/longhorn/longhorn-engine v1.5.5-0.20240319113652-9cdc0f5750a7/go.mod h1:JV0Wi1gcrttjzt/QmX2pyJJ5Pn3lm7woD2L9pk8GZFM= +github.com/longhorn/longhorn-instance-manager v1.5.5-0.20240326065406-8d925c0e7e1e h1:QqsxW3wfM7wuWHwG1g1UqxrSp7UPh7FrKbUNpL9EAWE= +github.com/longhorn/longhorn-instance-manager v1.5.5-0.20240326065406-8d925c0e7e1e/go.mod h1:2ggYNwWGMKAayH6y9PZ9smzi2aQioy8KFttPyjjaldc= +github.com/longhorn/longhorn-share-manager v1.5.5-0.20240319114127-58303a9ff61f h1:tEDeNKL5b+Zj+jaIAR/GFCnPBk34lhSad9Gol5PZTDM= +github.com/longhorn/longhorn-share-manager v1.5.5-0.20240319114127-58303a9ff61f/go.mod h1:nohk4hBmnbmsFi/TvsuWd14sh+BI9xPxuFg/0+BWq4Q= github.com/longhorn/longhorn-spdk-engine v0.0.0-20231005170812-e9b634e07e47 h1:hadV15fSF+akBFZ8dMQFscTsJUVpEC1t6Go3B28ZNYw= github.com/longhorn/longhorn-spdk-engine v0.0.0-20231005170812-e9b634e07e47/go.mod h1:mx8AOJWxLvWr+w4WtFirIPsEW88RajimS/pOEsw8A2k= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1196,6 +1162,8 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= @@ -1243,12 +1211,8 @@ github.com/rancher/dynamiclistener v0.3.6 h1:iAFWeiFNra6tYlt4k+jINrK3hOxZ8mjW2S/ github.com/rancher/dynamiclistener v0.3.6/go.mod h1:VqBaJNi+bZmre0+gi+2Jb6jbn7ovHzRueW+M7QhVKsk= github.com/rancher/go-rancher v0.1.1-0.20220412083059-ff12399dd57b h1:so40GMVZOZkQeIbAzaZRq6wDrMErvRLuXNsGTRZUpg8= github.com/rancher/go-rancher v0.1.1-0.20220412083059-ff12399dd57b/go.mod h1:7oQvGNiJsGvrUgB+7AH8bmdzuR0uhULfwKb43Ht0hUk= -github.com/rancher/lasso v0.0.0-20230830164424-d684fdeb6f29 h1:+kige/h8/LnzWgPjB5NUIHz/pWiW/lFpqcTUkN5uulY= -github.com/rancher/lasso v0.0.0-20230830164424-d684fdeb6f29/go.mod h1:kgk9kJVMj9FIrrXU0iyM6u/9Je4bEjPImqswkTVaKsQ= github.com/rancher/lasso v0.0.0-20240123150939-7055397d6dfa h1:eRhvQJjIpPxJunlS3e1J3qTghUy9MIrMjQa2aXYSC3k= github.com/rancher/lasso v0.0.0-20240123150939-7055397d6dfa/go.mod h1:utdskbIL7kdVvPCUFPEJQDWJwPHGFpUCRfVkX2G2Xxg= -github.com/rancher/wrangler v1.1.1 h1:wmqUwqc2M7ADfXnBCJTFkTB5ZREWpD78rnZMzmxwMvM= -github.com/rancher/wrangler v1.1.1/go.mod h1:ioVbKupzcBOdzsl55MvEDN0R1wdGggj8iNCYGFI5JvM= github.com/rancher/wrangler v1.1.2 h1:oXbXo9k7y/H4drUpb4RM1c++vT9O3rpoNEfyusGykiU= github.com/rancher/wrangler v1.1.2/go.mod h1:2k9MyhlBdjcutcBGoOJSUAz0HgDAXnMjv81d3n/AaQc= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -1271,6 +1235,10 @@ github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfF github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y= +github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -1322,13 +1290,13 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.13 h1:wsLILXG8qCJNse/qAgLNf23737Cx05GflHg/PJGe1Ok= -github.com/urfave/cli v1.22.13/go.mod h1:VufqObjsMTF2BBwKawpx9R8eAneNEWhoO0yx8Vd+FkE= github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM= @@ -1343,6 +1311,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1434,8 +1404,6 @@ golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1574,8 +1542,6 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1607,10 +1573,8 @@ golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= -golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0= -golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1627,10 +1591,9 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1648,6 +1611,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1676,6 +1640,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1737,10 +1702,10 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1752,8 +1717,6 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1773,8 +1736,6 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1941,7 +1902,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= @@ -2078,17 +2038,14 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 h1:9NWlQfY2ePejTmfwUH1OWwmznFa+0kKcHGPDvcPza9M= google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= -google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg= -google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= +google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= +google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= -google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 h1:m8v1xLLLzMe1m5P+gCTF8nJB9epwZQUBERm20Oy1poQ= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= -google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= +google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU= +google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= @@ -2131,10 +2088,9 @@ google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= -google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -2153,10 +2109,6 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -2227,8 +2179,9 @@ k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= +k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kms v0.28.2 h1:KhG63LHopCdzs1oKA1j+NWleuIXudgOyCqJo4yi3GaM= k8s.io/kms v0.28.2/go.mod h1:iAjgIqBrV2+8kmsjbbgUkAyKSuYq5g1dW9knpt6OhaE= k8s.io/kube-aggregator v0.28.2 h1:tCjAfB1p/v18yD2NpegNQRuahzyA/szFfcRARnpjDeo= @@ -2245,10 +2198,7 @@ k8s.io/mount-utils v0.28.2 h1:sIdMH7fRhcU48V1oYJ9cLmLm/TG+2jLhhe8eS3I+FWg= k8s.io/mount-utils v0.28.2/go.mod h1:AyP8LmZSLgpGdFQr+vzHTerlPiGvXUdP99n98Er47jw= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= diff --git a/types/device.go b/types/device.go index 01f0e2aead..a5935f64c8 100644 --- a/types/device.go +++ b/types/device.go @@ -9,13 +9,13 @@ import ( "github.com/pkg/errors" - "github.com/longhorn/longhorn-manager/util" + lhtypes "github.com/longhorn/go-common-libs/types" ) func GetDeviceTypeOf(mountPath string) (string, error) { procMountPaths := []string{ "/proc/mounts", - filepath.Join(util.HostProcPath, "1", "mounts"), + filepath.Join(lhtypes.HostProcDirectory, "1", "mounts"), } var devicePath string diff --git a/types/types.go b/types/types.go index 0acc92f0ae..4ff97cd8d4 100644 --- a/types/types.go +++ b/types/types.go @@ -10,10 +10,13 @@ import ( "sort" "strconv" "strings" + "time" "github.com/pkg/errors" "github.com/sirupsen/logrus" + lhns "github.com/longhorn/go-common-libs/ns" + "github.com/longhorn/longhorn-manager/util" longhorn "github.com/longhorn/longhorn-manager/k8s/pkg/apis/longhorn/v1beta2" @@ -858,7 +861,7 @@ func CreateDisksFromAnnotation(annotation string) (map[string]longhorn.DiskSpec, if disk.Path == "" { return nil, fmt.Errorf("invalid disk %+v", disk) } - diskStat, err := util.GetDiskStat(disk.Path) + diskStat, err := lhns.GetDiskStat(disk.Path) if err != nil { return nil, err } @@ -941,10 +944,10 @@ func UnmarshalToNodeTags(s string) ([]string, error) { } func CreateDefaultDisk(dataPath string, storageReservedPercentage int64) (map[string]longhorn.DiskSpec, error) { - if err := util.CreateDiskPathReplicaSubdirectory(dataPath); err != nil { - return nil, err + if _, err := lhns.CreateDirectory(filepath.Join(dataPath, util.ReplicaDirectory), time.Now()); err != nil { + return nil, errors.Wrapf(err, "failed to create replica subdirectory %v", dataPath) } - diskStat, err := util.GetDiskStat(dataPath) + diskStat, err := lhns.GetDiskStat(dataPath) if err != nil { return nil, err } diff --git a/util/os.go b/util/os.go deleted file mode 100644 index 80ef575f12..0000000000 --- a/util/os.go +++ /dev/null @@ -1,46 +0,0 @@ -package util - -import ( - "bufio" - "fmt" - "strings" - - "github.com/pkg/errors" - - iscsiutil "github.com/longhorn/go-iscsi-helper/util" -) - -const ( - OsReleasePath = "/etc/os-release" -) - -// GetHostKernelRelease retrieves the kernel release version of the host. -func GetHostKernelRelease() (string, error) { - initiatorNSPath := iscsiutil.GetHostNamespacePath(HostProcPath) - mountPath := fmt.Sprintf("--mount=%s/mnt", initiatorNSPath) - output, err := Execute([]string{}, "nsenter", mountPath, "uname", "-r") - if err != nil { - return "", err - } - return RemoveNewlines(output), nil -} - -// GetHostOSDistro retrieves the operating system distribution of the host. -func GetHostOSDistro() (string, error) { - initiatorNSPath := iscsiutil.GetHostNamespacePath(HostProcPath) - mountPath := fmt.Sprintf("--mount=%s/mnt", initiatorNSPath) - output, err := Execute([]string{}, "nsenter", mountPath, "cat", OsReleasePath) - if err != nil { - return "", errors.Wrapf(err, "failed to read %v on host", OsReleasePath) - } - - scanner := bufio.NewScanner(strings.NewReader(string(output))) - for scanner.Scan() { - line := scanner.Text() - if strings.HasPrefix(line, "ID=") { - osDistro := RemoveNewlines(strings.TrimPrefix(line, "ID=")) - return strings.ReplaceAll(osDistro, `"`, ""), nil - } - } - return "", fmt.Errorf("failed to find ID field in %v", OsReleasePath) -} diff --git a/util/os_test.go b/util/os_test.go deleted file mode 100644 index d9918fd15f..0000000000 --- a/util/os_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package util - -import ( - "bytes" - "fmt" - - . "gopkg.in/check.v1" -) - -func (s *TestSuite) TestGetHostOSDistro(c *C) { - type testCase struct { - mockExecute func([]string, string, ...string) (string, error) - - expected string - expectError bool - } - testCases := map[string]testCase{ - "get host OS distro": { - mockExecute: func([]string, string, ...string) (string, error) { - buffer := bytes.NewBufferString(`NAME="SLES" -VERSION="15-SP3" -VERSION_ID="15.3" -PRETTY_NAME="SUSE Linux Enterprise Server 15 SP3" -ID="sles" -ID_LIKE="suse"`) - return buffer.String(), nil - }, - expected: "sles", - expectError: false, - }, - "missing host OS distro": { - mockExecute: func([]string, string, ...string) (string, error) { - buffer := bytes.NewBufferString(`NAME="SLES" -VERSION="15-SP3" -VERSION_ID="15.3" -PRETTY_NAME="SUSE Linux Enterprise Server 15 SP3" -ID_LIKE="suse"`) - return buffer.String(), nil - }, - expected: "", - expectError: true, - }, - } - - for testName, testCase := range testCases { - fmt.Printf("testing %v\n", testName) - - Execute = testCase.mockExecute - - actual, err := GetHostOSDistro() - if !testCase.expectError { - c.Assert(err, IsNil, Commentf(TestErrErrorFmt, testName, err)) - } else { - c.Assert(err, NotNil) - } - - c.Assert(actual, Equals, testCase.expected, Commentf(TestErrResultFmt, testName)) - } -} diff --git a/util/util.go b/util/util.go index 66ef0b26c4..9dd93fc5bc 100644 --- a/util/util.go +++ b/util/util.go @@ -1,7 +1,6 @@ package util import ( - "bytes" "crypto/sha256" "crypto/sha512" "encoding/hex" @@ -14,7 +13,6 @@ import ( "net/http" "net/url" "os" - "os/exec" "os/signal" "path/filepath" "reflect" @@ -45,7 +43,9 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" clientset "k8s.io/client-go/kubernetes" - iscsiutil "github.com/longhorn/go-iscsi-helper/util" + lhio "github.com/longhorn/go-common-libs/io" + lhns "github.com/longhorn/go-common-libs/ns" + lhtypes "github.com/longhorn/go-common-libs/types" ) const ( @@ -82,7 +82,6 @@ const ( ) var ( - cmdTimeout = time.Minute // one minute by default reservedLabels = []string{"KubernetesStatus", "ranchervm-base-image"} APIRetryInterval = 500 * time.Millisecond @@ -97,17 +96,6 @@ type MetadataConfig struct { DriverContainerName string } -type DiskStat struct { - DiskID string - Path string - Type string - FreeBlocks int64 - TotalBlocks int64 - BlockSize int64 - StorageMaximum int64 - StorageAvailable int64 -} - func ConvertSize(size interface{}) (int64, error) { switch size := size.(type) { case int64: @@ -251,67 +239,6 @@ func ParseTime(t string) (time.Time, error) { } -type ExecuteFunc func([]string, string, ...string) (string, error) - -// Execute is a variable holding the function responsible for executing commands. -// By using a variable for the execution function, it allows for easier unit testing -// by substituting a mock implementation. -var Execute ExecuteFunc = execute - -func execute(envs []string, binary string, args ...string) (string, error) { - return ExecuteWithTimeout(cmdTimeout, envs, binary, args...) -} - -func ExecuteWithTimeout(timeout time.Duration, envs []string, binary string, args ...string) (string, error) { - var err error - cmd := exec.Command(binary, args...) - cmd.Env = append(os.Environ(), envs...) - done := make(chan struct{}) - - var output, stderr bytes.Buffer - cmd.Stdout = &output - cmd.Stderr = &stderr - - go func() { - err = cmd.Run() - done <- struct{}{} - }() - - select { - case <-done: - case <-time.After(timeout): - if cmd.Process != nil { - if err := cmd.Process.Kill(); err != nil { - logrus.Warnf("Problem killing process pid=%v: %s", cmd.Process.Pid, err) - } - - } - return "", fmt.Errorf("timeout executing: %v %v, output %s, stderr, %s, error %v", - binary, args, output.String(), stderr.String(), err) - } - - if err != nil { - return "", fmt.Errorf("failed to execute: %v %v, output %s, stderr, %s, error %v", - binary, args, output.String(), stderr.String(), err) - } - return output.String(), nil -} - -func ExecuteWithoutTimeout(envs []string, binary string, args ...string) (string, error) { - cmd := exec.Command(binary, args...) - cmd.Env = append(os.Environ(), envs...) - - var output, stderr bytes.Buffer - cmd.Stdout = &output - cmd.Stderr = &stderr - - if err := cmd.Run(); err != nil { - return output.String(), fmt.Errorf("failed to execute: %v %v, output %s, stderr, %s, error %v", - binary, args, output.String(), stderr.String(), err) - } - return output.String(), nil -} - func TimestampAfterTimeout(ts string, timeout time.Duration) bool { now := time.Now() t, err := time.Parse(time.RFC3339, ts) @@ -491,45 +418,6 @@ func CheckBackupType(backupTarget string) (string, error) { return u.Scheme, nil } -type FsStat struct { - Fsid string - Path string - Type string - FreeBlock int64 - TotalBlock int64 - BlockSize int64 -} - -func GetDiskStat(directory string) (stat *DiskStat, err error) { - defer func() { - err = errors.Wrapf(err, "cannot get disk stat of directory %v", directory) - }() - initiatorNSPath := iscsiutil.GetHostNamespacePath(HostProcPath) - mountPath := fmt.Sprintf("--mount=%s/mnt", initiatorNSPath) - output, err := Execute([]string{}, "nsenter", mountPath, "stat", "-fc", "{\"path\":\"%n\",\"fsid\":\"%i\",\"type\":\"%T\",\"freeBlock\":%f,\"totalBlock\":%b,\"blockSize\":%S}", directory) - if err != nil { - return nil, err - } - output = strings.Replace(output, "\n", "", -1) - - fsStat := &FsStat{} - err = json.Unmarshal([]byte(output), fsStat) - if err != nil { - return nil, err - } - - return &DiskStat{ - DiskID: fsStat.Fsid, - Path: fsStat.Path, - Type: fsStat.Type, - FreeBlocks: fsStat.FreeBlock, - TotalBlocks: fsStat.TotalBlock, - BlockSize: fsStat.BlockSize, - StorageMaximum: fsStat.TotalBlock * fsStat.BlockSize, - StorageAvailable: fsStat.FreeBlock * fsStat.BlockSize, - }, nil -} - func RetryOnConflictCause(fn func() (interface{}, error)) (interface{}, error) { return RetryOnErrorCondition(fn, apierrors.IsConflict) } @@ -560,34 +448,6 @@ func RunAsync(wg *sync.WaitGroup, f func()) { }() } -func RemoveHostDirectoryContent(directory string) (err error) { - defer func() { - err = errors.Wrapf(err, "failed to remove host directory %v", directory) - }() - - dir, err := filepath.Abs(filepath.Clean(directory)) - if err != nil { - return err - } - if strings.Count(dir, "/") < 2 { - return fmt.Errorf("prohibit removing the top level of directory %v", dir) - } - initiatorNSPath := iscsiutil.GetHostNamespacePath(HostProcPath) - nsExec, err := iscsiutil.NewNamespaceExecutor(initiatorNSPath) - if err != nil { - return err - } - // check if the directory already deleted - if _, err := nsExec.Execute("ls", []string{dir}); err != nil { - logrus.Warnf("cannot find host directory %v for removal", dir) - return nil - } - if _, err := nsExec.Execute("rm", []string{"-rf", dir}); err != nil { - return err - } - return nil -} - type filteredLoggingHandler struct { filteredPaths map[string]struct{} handler http.Handler @@ -656,41 +516,26 @@ func ValidateTags(inputTags []string) ([]string, error) { return tags, nil } -func CreateDiskPathReplicaSubdirectory(path string) error { - nsPath := iscsiutil.GetHostNamespacePath(HostProcPath) - nsExec, err := iscsiutil.NewNamespaceExecutor(nsPath) - if err != nil { - return err - } - if _, err := nsExec.Execute("mkdir", []string{"-p", filepath.Join(path, ReplicaDirectory)}); err != nil { - return errors.Wrapf(err, "error creating data path %v on host", path) - } - - return nil -} - -func DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile( - nsExec *iscsiutil.NamespaceExecutor, path string) error { +func DeleteDiskPathReplicaSubdirectoryAndDiskCfgFile(path string) error { + replicaDirectoryPath := filepath.Join(path, ReplicaDirectory) + diskCfgFilePath := filepath.Join(path, DiskConfigFile) - var err error - dirPath := filepath.Join(path, ReplicaDirectory) - filePath := filepath.Join(path, DiskConfigFile) - - // Check if the replica directory exist, delete it - if _, err := nsExec.Execute("ls", []string{dirPath}); err == nil { - if _, err := nsExec.Execute("rmdir", []string{dirPath}); err != nil { - return errors.Wrapf(err, "error deleting data path %v on host", path) + // Delete the replica directory on host + if _, err := lhns.GetFileInfo(replicaDirectoryPath); err == nil { + logrus.Tracef("Deleting replica directory %v", replicaDirectoryPath) + if err := lhns.DeletePath(replicaDirectoryPath); err != nil { + return errors.Wrapf(err, "failed to delete host replica directory %v", replicaDirectoryPath) } } - // Check if the disk cfg file exist, delete it - if _, err := nsExec.Execute("ls", []string{filePath}); err == nil { - if _, err := nsExec.Execute("rm", []string{filePath}); err != nil { - err = errors.Wrapf(err, "error deleting disk cfg file %v on host", filePath) + if _, err := lhns.GetFileInfo(diskCfgFilePath); err == nil { + logrus.Tracef("Deleting disk cfg file %v", diskCfgFilePath) + if err := lhns.DeletePath(diskCfgFilePath); err != nil { + return errors.Wrapf(err, "failed to delete host disk cfg file %v", diskCfgFilePath) } } - return err + return nil } func IsKubernetesDefaultToleration(toleration corev1.Toleration) bool { @@ -810,44 +655,26 @@ func GetPossibleReplicaDirectoryNames(diskPath string) (replicaDirectoryNames ma }() replicaDirectoryNames = make(map[string]string, 0) + path := filepath.Join(diskPath, "replicas") - directory := filepath.Join(diskPath, "replicas") - - initiatorNSPath := iscsiutil.GetHostNamespacePath(HostProcPath) - mountPath := fmt.Sprintf("--mount=%s/mnt", initiatorNSPath) - command := fmt.Sprintf("find %s -type d -maxdepth 1 -mindepth 1 -regextype posix-extended -regex \".*-[a-zA-Z0-9]{8}$\" -exec basename {} \\;", directory) - output, err := Execute([]string{}, "nsenter", mountPath, "sh", "-c", command) + files, err := lhns.ReadDirectory(path) if err != nil { return replicaDirectoryNames, err } - names := strings.Split(output, "\n") - for _, name := range names { - if name != "" { - replicaDirectoryNames[name] = "" + // Compile the regular expression pattern + pattern := regexp.MustCompile(`.*-[a-zA-Z0-9]{8}$`) + + // Iterate over the files and filter directories based on the pattern + for _, file := range files { + if file.IsDir() && pattern.MatchString(file.Name()) { + replicaDirectoryNames[file.Name()] = "" } } return replicaDirectoryNames, nil } -func DeleteReplicaDirectory(diskPath, replicaDirectoryName string) (err error) { - defer func() { - err = errors.Wrapf(err, "cannot delete replica directory %v in disk %v", replicaDirectoryName, diskPath) - }() - - path := filepath.Join(diskPath, "replicas", replicaDirectoryName) - - initiatorNSPath := iscsiutil.GetHostNamespacePath(HostProcPath) - mountPath := fmt.Sprintf("--mount=%s/mnt", initiatorNSPath) - _, err = Execute([]string{}, "nsenter", mountPath, "rm", "-rf", path) - if err != nil { - return err - } - - return nil -} - type VolumeMeta struct { Size int64 Head string @@ -861,13 +688,7 @@ type VolumeMeta struct { } func GetVolumeMeta(path string) (*VolumeMeta, error) { - nsPath := iscsiutil.GetHostNamespacePath(HostProcPath) - nsExec, err := iscsiutil.NewNamespaceExecutor(nsPath) - if err != nil { - return nil, err - } - - output, err := nsExec.Execute("cat", []string{path}) + output, err := lhns.ReadFileContent(path) if err != nil { return nil, fmt.Errorf("cannot find volume meta %v on host: %v", path, err) } @@ -891,44 +712,68 @@ func GetPodIP(pod *corev1.Pod) (string, error) { } func TrimFilesystem(volumeName string, encryptedDevice bool) error { - nsPath := iscsiutil.GetHostNamespacePath(HostProcPath) - nsExec, err := iscsiutil.NewNamespaceExecutor(nsPath) + var err error + defer func() { + err = errors.Wrapf(err, "failed to trim filesystem for Volume %v", volumeName) + }() + + validMountpoint, err := getValidMountPoint(volumeName, lhtypes.HostProcDirectory, encryptedDevice) if err != nil { return err } - deviceDir := RegularDeviceDirectory - if encryptedDevice { - deviceDir = EncryptedDeviceDirectory + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceNet} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.HostProcDirectory, namespaces) + if err != nil { + return err } - mountOutput, err := nsExec.Execute("bash", []string{"-c", fmt.Sprintf("cat /proc/mounts | grep %s%s | awk '{print $2}'", deviceDir, volumeName)}) + _, err = nsexec.Execute(nil, lhtypes.BinaryFstrim, []string{validMountpoint}, lhtypes.ExecuteDefaultTimeout) if err != nil { return errors.Wrapf(err, "cannot find volume %v mount info on host", volumeName) } - mountList := strings.Split(strings.TrimSpace(mountOutput), "\n") + return nil +} - var mountpoint string - for _, m := range mountList { - _, err = nsExec.Execute("stat", []string{m}) +func getValidMountPoint(volumeName, procDir string, encryptedDevice bool) (string, error) { + procMountsPath := filepath.Join(procDir, "1", "mounts") + content, err := lhio.ReadFileContent(procMountsPath) + if err != nil { + return "", err + } + + deviceDir := RegularDeviceDirectory + if encryptedDevice { + deviceDir = EncryptedDeviceDirectory + } + + var validMountpoint string + lines := strings.Split(content, "\n") + for _, line := range lines { + fields := strings.Fields(line) + if len(fields) < 2 { + continue + } + + device := fields[0] + if !strings.HasPrefix(device, deviceDir+volumeName) { + continue + } + + mountPoint := fields[1] + _, err = lhns.GetFileInfo(mountPoint) if err == nil { - mountpoint = m + validMountpoint = mountPoint break } - - logrus.WithError(err).Warnf("Failed to get volume %v mount point %v info", volumeName, m) - } - if mountpoint == "" { - return fmt.Errorf("cannot find a valid mount point for volume %v", volumeName) } - _, err = nsExec.Execute("fstrim", []string{mountpoint}) - if err != nil { - return errors.Wrapf(err, "cannot find volume %v mount info on host", volumeName) + if validMountpoint == "" { + return "", fmt.Errorf("failed to find valid mountpoint") } - return nil + return validMountpoint, nil } // SortKeys accepts a map with string keys and returns a sorted slice of keys diff --git a/util/util_test.go b/util/util_test.go index 904aef8dd2..a56363fbd3 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -1,13 +1,20 @@ package util import ( + "fmt" + "io" + "os" + "path/filepath" + "strings" "testing" "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" . "gopkg.in/check.v1" + + lhfake "github.com/longhorn/go-common-libs/test/fake" + lhtypes "github.com/longhorn/go-common-libs/types" ) const ( @@ -72,30 +79,106 @@ func TestDeterministicUUID(t *testing.T) { assert.Equal(DeterministicUUID(dataUsedToGenerate), DeterministicUUID(dataUsedToGenerate)) } -func TestTimestampAfterTimestamp(t *testing.T) { - tests := map[string]struct { - timestamp1 string - timestamp2 string - want bool - wantErr bool - }{ - "timestamp1BadFormat": {"2024-01-02T18:37Z", "2024-01-02T18:16:37Z", false, true}, - "timestamp2BadFormat": {"2024-01-02T18:16:37Z", "2024-01-02T18:37Z", false, true}, - "timestamp1After": {"2024-01-02T18:17:37Z", "2024-01-02T18:16:37Z", true, false}, - "timestamp1NotAfter": {"2024-01-02T18:16:37Z", "2024-01-02T18:17:37Z", false, false}, - "sameTime": {"2024-01-02T18:16:37Z", "2024-01-02T18:16:37Z", false, false}, +func (s *TestSuite) TestGetValidMountPoint(c *C) { + // Check if the /host/proc directory exists in container + if _, err := os.Stat(lhtypes.HostProcDirectory); os.IsNotExist(err) { + // Create a symbolic link from /proc to /host/proc + err := os.Symlink("/proc", "/host/proc") + c.Assert(err, IsNil) + defer func() { + _ = os.Remove(lhtypes.HostProcDirectory) + }() + } + + fakeDir := lhfake.CreateTempDirectory("", c) + defer func() { + _ = os.RemoveAll(fakeDir) + }() + + fakeVolumeName := "volume" + fakeMountFileName := "mount-file" + fakeProcMountFile := func(procDir, mountFilePath string, isEncryptedDevice bool) { + // Create a proc PID directory + procPidDir := filepath.Join(procDir, "1") + err := os.Mkdir(procPidDir, 0755) + c.Assert(err, IsNil) + + // Create a mount file + fakeProcMountFile := lhfake.CreateTempFile(procPidDir, "mounts", "mock\n", c) + + // Seek to the end of the file and write a byte + _, err = fakeProcMountFile.Seek(0, io.SeekEnd) + c.Assert(err, IsNil) + + // Define the device path + devicePath := filepath.Join("/dev/longhorn", fakeVolumeName) + if isEncryptedDevice { + devicePath = filepath.Join("/dev/mapper", fakeVolumeName) + } + + content := fmt.Sprintf("%s %s ext4 rw,relatime 0 0", devicePath, mountFilePath) + _, err = fakeProcMountFile.WriteString(content) + c.Assert(err, IsNil) + + // Read the file content + readContent, err := os.ReadFile(fakeProcMountFile.Name()) + c.Assert(err, IsNil) + + // Convert the read content to string and split by lines + lines := strings.Split(string(readContent), "\n") + + // Assert the number of lines and their content + c.Assert(len(lines), Equals, 2) + + err = fakeProcMountFile.Close() + c.Assert(err, IsNil) } - assert := assert.New(t) - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - got, err := TimestampAfterTimestamp(tc.timestamp1, tc.timestamp2) - assert.Equal(tc.want, got) - if tc.wantErr { - assert.Error(err) - } else { - assert.NoError(err) - } - }) + type testCase struct { + isEncryptedDevice bool + isInvalidMountPath bool + isInvalidMountPointPath bool + isExpectingError bool + } + testCases := map[string]testCase{ + "getValidMountPoint(...)": { + isEncryptedDevice: false, + }, + "getValidMountPoint(...) with encrypted device": { + isEncryptedDevice: true, + }, + "getValidMountPoint(...) with invalid mount path": { + isInvalidMountPath: true, + isExpectingError: true, + }, + "getValidMountPoint(...) with invalid mount point path": { + isInvalidMountPointPath: true, + isExpectingError: true, + }, + } + for testName, testCase := range testCases { + c.Logf("testing util.%v", testName) + + fakeProcDir := lhfake.CreateTempDirectory(fakeDir, c) + + expectedMountPointPath := filepath.Join(fakeProcDir, fakeMountFileName) + + if !testCase.isInvalidMountPath { + fakeProcMountFile(fakeProcDir, expectedMountPointPath, testCase.isEncryptedDevice) + } + + if !testCase.isInvalidMountPointPath { + fakeMountFile := lhfake.CreateTempFile(fakeProcDir, fakeMountFileName, "mock", c) + err := fakeMountFile.Close() + c.Assert(err, IsNil) + } + + validMountPoint, err := getValidMountPoint(fakeVolumeName, fakeProcDir, testCase.isEncryptedDevice) + if testCase.isExpectingError { + c.Assert(err, NotNil) + } else { + c.Assert(err, IsNil) + c.Assert(validMountPoint, Equals, expectedMountPointPath) + } } } diff --git a/vendor/github.com/go-logr/logr/README.md b/vendor/github.com/go-logr/logr/README.md index ab59311813..a8c29bfbd5 100644 --- a/vendor/github.com/go-logr/logr/README.md +++ b/vendor/github.com/go-logr/logr/README.md @@ -1,6 +1,7 @@ # A minimal logging API for Go [![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-logr/logr/badge)](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr) logr offers an(other) opinion on how Go programs and libraries can do logging without becoming coupled to a particular logging implementation. This is not @@ -73,6 +74,29 @@ received: If the Go standard library had defined an interface for logging, this project probably would not be needed. Alas, here we are. +When the Go developers started developing such an interface with +[slog](https://github.com/golang/go/issues/56345), they adopted some of the +logr design but also left out some parts and changed others: + +| Feature | logr | slog | +|---------|------|------| +| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) | +| Low-level API | `LogSink` | `Handler` | +| Stack unwinding | done by `LogSink` | done by `Logger` | +| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) | +| Generating a value for logging on demand | `Marshaler` | `LogValuer` | +| Log levels | >= 0, higher meaning "less important" | positive and negative, with 0 for "info" and higher meaning "more important" | +| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` | +| Passing logger via context | `NewContext`, `FromContext` | no API | +| Adding a name to a logger | `WithName` | no API | +| Modify verbosity of log entries in a call chain | `V` | no API | +| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` | + +The high-level slog API is explicitly meant to be one of many different APIs +that can be layered on top of a shared `slog.Handler`. logr is one such +alternative API, with [interoperability](#slog-interoperability) provided by the [`slogr`](slogr) +package. + ### Inspiration Before you consider this package, please read [this blog post by the @@ -118,6 +142,91 @@ There are implementations for the following logging libraries: - **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0) - **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing) +## slog interoperability + +Interoperability goes both ways, using the `logr.Logger` API with a `slog.Handler` +and using the `slog.Logger` API with a `logr.LogSink`. [slogr](./slogr) provides `NewLogr` and +`NewSlogHandler` API calls to convert between a `logr.Logger` and a `slog.Handler`. +As usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level +slog API. `slogr` itself leaves that to the caller. + +## Using a `logr.Sink` as backend for slog + +Ideally, a logr sink implementation should support both logr and slog by +implementing both the normal logr interface(s) and `slogr.SlogSink`. Because +of a conflict in the parameters of the common `Enabled` method, it is [not +possible to implement both slog.Handler and logr.Sink in the same +type](https://github.com/golang/go/issues/59110). + +If both are supported, log calls can go from the high-level APIs to the backend +without the need to convert parameters. `NewLogr` and `NewSlogHandler` can +convert back and forth without adding additional wrappers, with one exception: +when `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then +`NewSlogHandler` has to use a wrapper which adjusts the verbosity for future +log calls. + +Such an implementation should also support values that implement specific +interfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`, +`slog.GroupValue`). logr does not convert those. + +Not supporting slog has several drawbacks: +- Recording source code locations works correctly if the handler gets called + through `slog.Logger`, but may be wrong in other cases. That's because a + `logr.Sink` does its own stack unwinding instead of using the program counter + provided by the high-level API. +- slog levels <= 0 can be mapped to logr levels by negating the level without a + loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as + used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink + because logr does not support "more important than info" levels. +- The slog group concept is supported by prefixing each key in a key/value + pair with the group names, separated by a dot. For structured output like + JSON it would be better to group the key/value pairs inside an object. +- Special slog values and interfaces don't work as expected. +- The overhead is likely to be higher. + +These drawbacks are severe enough that applications using a mixture of slog and +logr should switch to a different backend. + +## Using a `slog.Handler` as backend for logr + +Using a plain `slog.Handler` without support for logr works better than the +other direction: +- All logr verbosity levels can be mapped 1:1 to their corresponding slog level + by negating them. +- Stack unwinding is done by the `slogr.SlogSink` and the resulting program + counter is passed to the `slog.Handler`. +- Names added via `Logger.WithName` are gathered and recorded in an additional + attribute with `logger` as key and the names separated by slash as value. +- `Logger.Error` is turned into a log record with `slog.LevelError` as level + and an additional attribute with `err` as key, if an error was provided. + +The main drawback is that `logr.Marshaler` will not be supported. Types should +ideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility +with logr implementations without slog support is not important, then +`slog.Valuer` is sufficient. + +## Context support for slog + +Storing a logger in a `context.Context` is not supported by +slog. `logr.NewContext` and `logr.FromContext` can be used with slog like this +to fill this gap: + + func HandlerFromContext(ctx context.Context) slog.Handler { + logger, err := logr.FromContext(ctx) + if err == nil { + return slogr.NewSlogHandler(logger) + } + return slog.Default().Handler() + } + + func ContextWithHandler(ctx context.Context, handler slog.Handler) context.Context { + return logr.NewContext(ctx, slogr.NewLogr(handler)) + } + +The downside is that storing and retrieving a `slog.Handler` needs more +allocations compared to using a `logr.Logger`. Therefore the recommendation is +to use the `logr.Logger` API in code which uses contextual logging. + ## FAQ ### Conceptual @@ -241,7 +350,9 @@ Otherwise, you can start out with `0` as "you always want to see this", Then gradually choose levels in between as you need them, working your way down from 10 (for debug and trace style logs) and up from 1 (for chattier -info-type logs.) +info-type logs). For reference, slog pre-defines -4 for debug logs +(corresponds to 4 in logr), which matches what is +[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use). #### How do I choose my keys? diff --git a/vendor/github.com/go-logr/logr/SECURITY.md b/vendor/github.com/go-logr/logr/SECURITY.md new file mode 100644 index 0000000000..1ca756fc7b --- /dev/null +++ b/vendor/github.com/go-logr/logr/SECURITY.md @@ -0,0 +1,18 @@ +# Security Policy + +If you have discovered a security vulnerability in this project, please report it +privately. **Do not disclose it as a public issue.** This gives us time to work with you +to fix the issue before public exposure, reducing the chance that the exploit will be +used before a patch is released. + +You may submit the report in the following ways: + +- send an email to go-logr-security@googlegroups.com +- send us a [private vulnerability report](https://github.com/go-logr/logr/security/advisories/new) + +Please provide the following information in your report: + +- A description of the vulnerability and its impact +- How to reproduce the issue + +We ask that you give us 90 days to work on a fix before public exposure. diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go index e52f0cd01e..12e5807cc5 100644 --- a/vendor/github.com/go-logr/logr/funcr/funcr.go +++ b/vendor/github.com/go-logr/logr/funcr/funcr.go @@ -116,17 +116,17 @@ type Options struct { // Equivalent hooks are offered for key-value pairs saved via // logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and // for user-provided pairs (see RenderArgsHook). - RenderBuiltinsHook func(kvList []interface{}) []interface{} + RenderBuiltinsHook func(kvList []any) []any // RenderValuesHook is the same as RenderBuiltinsHook, except that it is // only called for key-value pairs saved via logr.Logger.WithValues. See // RenderBuiltinsHook for more details. - RenderValuesHook func(kvList []interface{}) []interface{} + RenderValuesHook func(kvList []any) []any // RenderArgsHook is the same as RenderBuiltinsHook, except that it is only // called for key-value pairs passed directly to Info and Error. See // RenderBuiltinsHook for more details. - RenderArgsHook func(kvList []interface{}) []interface{} + RenderArgsHook func(kvList []any) []any // MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct // that contains a struct, etc.) it may log. Every time it finds a struct, @@ -163,7 +163,7 @@ func (l fnlogger) WithName(name string) logr.LogSink { return &l } -func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink { +func (l fnlogger) WithValues(kvList ...any) logr.LogSink { l.Formatter.AddValues(kvList) return &l } @@ -173,12 +173,12 @@ func (l fnlogger) WithCallDepth(depth int) logr.LogSink { return &l } -func (l fnlogger) Info(level int, msg string, kvList ...interface{}) { +func (l fnlogger) Info(level int, msg string, kvList ...any) { prefix, args := l.FormatInfo(level, msg, kvList) l.write(prefix, args) } -func (l fnlogger) Error(err error, msg string, kvList ...interface{}) { +func (l fnlogger) Error(err error, msg string, kvList ...any) { prefix, args := l.FormatError(err, msg, kvList) l.write(prefix, args) } @@ -229,7 +229,7 @@ func newFormatter(opts Options, outfmt outputFormat) Formatter { type Formatter struct { outputFormat outputFormat prefix string - values []interface{} + values []any valuesStr string depth int opts *Options @@ -246,10 +246,10 @@ const ( ) // PseudoStruct is a list of key-value pairs that gets logged as a struct. -type PseudoStruct []interface{} +type PseudoStruct []any // render produces a log line, ready to use. -func (f Formatter) render(builtins, args []interface{}) string { +func (f Formatter) render(builtins, args []any) string { // Empirically bytes.Buffer is faster than strings.Builder for this. buf := bytes.NewBuffer(make([]byte, 0, 1024)) if f.outputFormat == outputJSON { @@ -292,7 +292,7 @@ func (f Formatter) render(builtins, args []interface{}) string { // This function returns a potentially modified version of kvList, which // ensures that there is a value for every key (adding a value if needed) and // that each key is a string (substituting a key if needed). -func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} { +func (f Formatter) flatten(buf *bytes.Buffer, kvList []any, continuing bool, escapeKeys bool) []any { // This logic overlaps with sanitize() but saves one type-cast per key, // which can be measurable. if len(kvList)%2 != 0 { @@ -334,7 +334,7 @@ func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing b return kvList } -func (f Formatter) pretty(value interface{}) string { +func (f Formatter) pretty(value any) string { return f.prettyWithFlags(value, 0, 0) } @@ -343,7 +343,7 @@ const ( ) // TODO: This is not fast. Most of the overhead goes here. -func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string { +func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string { if depth > f.opts.MaxLogDepth { return `""` } @@ -614,7 +614,7 @@ func isEmpty(v reflect.Value) bool { return false } -func invokeMarshaler(m logr.Marshaler) (ret interface{}) { +func invokeMarshaler(m logr.Marshaler) (ret any) { defer func() { if r := recover(); r != nil { ret = fmt.Sprintf("", r) @@ -675,12 +675,12 @@ func (f Formatter) caller() Caller { const noValue = "" -func (f Formatter) nonStringKey(v interface{}) string { +func (f Formatter) nonStringKey(v any) string { return fmt.Sprintf("", f.snippet(v)) } // snippet produces a short snippet string of an arbitrary value. -func (f Formatter) snippet(v interface{}) string { +func (f Formatter) snippet(v any) string { const snipLen = 16 snip := f.pretty(v) @@ -693,7 +693,7 @@ func (f Formatter) snippet(v interface{}) string { // sanitize ensures that a list of key-value pairs has a value for every key // (adding a value if needed) and that each key is a string (substituting a key // if needed). -func (f Formatter) sanitize(kvList []interface{}) []interface{} { +func (f Formatter) sanitize(kvList []any) []any { if len(kvList)%2 != 0 { kvList = append(kvList, noValue) } @@ -727,8 +727,8 @@ func (f Formatter) GetDepth() int { // FormatInfo renders an Info log message into strings. The prefix will be // empty when no names were set (via AddNames), or when the output is // configured for JSON. -func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf +func (f Formatter) FormatInfo(level int, msg string, kvList []any) (prefix, argsStr string) { + args := make([]any, 0, 64) // using a constant here impacts perf prefix = f.prefix if f.outputFormat == outputJSON { args = append(args, "logger", prefix) @@ -745,10 +745,10 @@ func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (pref } // FormatError renders an Error log message into strings. The prefix will be -// empty when no names were set (via AddNames), or when the output is +// empty when no names were set (via AddNames), or when the output is // configured for JSON. -func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) { - args := make([]interface{}, 0, 64) // using a constant here impacts perf +func (f Formatter) FormatError(err error, msg string, kvList []any) (prefix, argsStr string) { + args := make([]any, 0, 64) // using a constant here impacts perf prefix = f.prefix if f.outputFormat == outputJSON { args = append(args, "logger", prefix) @@ -761,12 +761,12 @@ func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (pre args = append(args, "caller", f.caller()) } args = append(args, "msg", msg) - var loggableErr interface{} + var loggableErr any if err != nil { loggableErr = err.Error() } args = append(args, "error", loggableErr) - return f.prefix, f.render(args, kvList) + return prefix, f.render(args, kvList) } // AddName appends the specified name. funcr uses '/' characters to separate @@ -781,7 +781,7 @@ func (f *Formatter) AddName(name string) { // AddValues adds key-value pairs to the set of saved values to be logged with // each log line. -func (f *Formatter) AddValues(kvList []interface{}) { +func (f *Formatter) AddValues(kvList []any) { // Three slice args forces a copy. n := len(f.values) f.values = append(f.values[:n:n], kvList...) diff --git a/vendor/github.com/go-logr/logr/logr.go b/vendor/github.com/go-logr/logr/logr.go index e027aea3fd..2a5075a180 100644 --- a/vendor/github.com/go-logr/logr/logr.go +++ b/vendor/github.com/go-logr/logr/logr.go @@ -127,9 +127,9 @@ limitations under the License. // such a value can call its methods without having to check whether the // instance is ready for use. // -// Calling methods with the null logger (Logger{}) as instance will crash -// because it has no LogSink. Therefore this null logger should never be passed -// around. For cases where passing a logger is optional, a pointer to Logger +// The zero logger (= Logger{}) is identical to Discard() and discards all log +// entries. Code that receives a Logger by value can simply call it, the methods +// will never crash. For cases where passing a logger is optional, a pointer to Logger // should be used. // // # Key Naming Conventions @@ -258,6 +258,12 @@ type Logger struct { // Enabled tests whether this Logger is enabled. For example, commandline // flags might be used to set the logging verbosity and disable some info logs. func (l Logger) Enabled() bool { + // Some implementations of LogSink look at the caller in Enabled (e.g. + // different verbosity levels per package or file), but we only pass one + // CallDepth in (via Init). This means that all calls from Logger to the + // LogSink's Enabled, Info, and Error methods must have the same number of + // frames. In other words, Logger methods can't call other Logger methods + // which call these LogSink methods unless we do it the same in all paths. return l.sink != nil && l.sink.Enabled(l.level) } @@ -267,11 +273,11 @@ func (l Logger) Enabled() bool { // line. The key/value pairs can then be used to add additional variable // information. The key/value pairs must alternate string keys and arbitrary // values. -func (l Logger) Info(msg string, keysAndValues ...interface{}) { +func (l Logger) Info(msg string, keysAndValues ...any) { if l.sink == nil { return } - if l.Enabled() { + if l.sink.Enabled(l.level) { // see comment in Enabled if withHelper, ok := l.sink.(CallStackHelperLogSink); ok { withHelper.GetCallStackHelper()() } @@ -289,7 +295,7 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) { // while the err argument should be used to attach the actual error that // triggered this log line, if present. The err parameter is optional // and nil may be passed instead of an error instance. -func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) { +func (l Logger) Error(err error, msg string, keysAndValues ...any) { if l.sink == nil { return } @@ -314,9 +320,16 @@ func (l Logger) V(level int) Logger { return l } +// GetV returns the verbosity level of the logger. If the logger's LogSink is +// nil as in the Discard logger, this will always return 0. +func (l Logger) GetV() int { + // 0 if l.sink nil because of the if check in V above. + return l.level +} + // WithValues returns a new Logger instance with additional key/value pairs. // See Info for documentation on how key/value pairs work. -func (l Logger) WithValues(keysAndValues ...interface{}) Logger { +func (l Logger) WithValues(keysAndValues ...any) Logger { if l.sink == nil { return l } @@ -467,15 +480,15 @@ type LogSink interface { // The level argument is provided for optional logging. This method will // only be called when Enabled(level) is true. See Logger.Info for more // details. - Info(level int, msg string, keysAndValues ...interface{}) + Info(level int, msg string, keysAndValues ...any) // Error logs an error, with the given message and key/value pairs as // context. See Logger.Error for more details. - Error(err error, msg string, keysAndValues ...interface{}) + Error(err error, msg string, keysAndValues ...any) // WithValues returns a new LogSink with additional key/value pairs. See // Logger.WithValues for more details. - WithValues(keysAndValues ...interface{}) LogSink + WithValues(keysAndValues ...any) LogSink // WithName returns a new LogSink with the specified name appended. See // Logger.WithName for more details. @@ -546,5 +559,5 @@ type Marshaler interface { // with exported fields // // It may return any value of any type. - MarshalLog() interface{} + MarshalLog() any } diff --git a/vendor/github.com/go-logr/logr/slogr/sloghandler.go b/vendor/github.com/go-logr/logr/slogr/sloghandler.go new file mode 100644 index 0000000000..ec6725ce2c --- /dev/null +++ b/vendor/github.com/go-logr/logr/slogr/sloghandler.go @@ -0,0 +1,168 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The logr Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package slogr + +import ( + "context" + "log/slog" + + "github.com/go-logr/logr" +) + +type slogHandler struct { + // May be nil, in which case all logs get discarded. + sink logr.LogSink + // Non-nil if sink is non-nil and implements SlogSink. + slogSink SlogSink + + // groupPrefix collects values from WithGroup calls. It gets added as + // prefix to value keys when handling a log record. + groupPrefix string + + // levelBias can be set when constructing the handler to influence the + // slog.Level of log records. A positive levelBias reduces the + // slog.Level value. slog has no API to influence this value after the + // handler got created, so it can only be set indirectly through + // Logger.V. + levelBias slog.Level +} + +var _ slog.Handler = &slogHandler{} + +// groupSeparator is used to concatenate WithGroup names and attribute keys. +const groupSeparator = "." + +// GetLevel is used for black box unit testing. +func (l *slogHandler) GetLevel() slog.Level { + return l.levelBias +} + +func (l *slogHandler) Enabled(ctx context.Context, level slog.Level) bool { + return l.sink != nil && (level >= slog.LevelError || l.sink.Enabled(l.levelFromSlog(level))) +} + +func (l *slogHandler) Handle(ctx context.Context, record slog.Record) error { + if l.slogSink != nil { + // Only adjust verbosity level of log entries < slog.LevelError. + if record.Level < slog.LevelError { + record.Level -= l.levelBias + } + return l.slogSink.Handle(ctx, record) + } + + // No need to check for nil sink here because Handle will only be called + // when Enabled returned true. + + kvList := make([]any, 0, 2*record.NumAttrs()) + record.Attrs(func(attr slog.Attr) bool { + if attr.Key != "" { + kvList = append(kvList, l.addGroupPrefix(attr.Key), attr.Value.Resolve().Any()) + } + return true + }) + if record.Level >= slog.LevelError { + l.sinkWithCallDepth().Error(nil, record.Message, kvList...) + } else { + level := l.levelFromSlog(record.Level) + l.sinkWithCallDepth().Info(level, record.Message, kvList...) + } + return nil +} + +// sinkWithCallDepth adjusts the stack unwinding so that when Error or Info +// are called by Handle, code in slog gets skipped. +// +// This offset currently (Go 1.21.0) works for calls through +// slog.New(NewSlogHandler(...)). There's no guarantee that the call +// chain won't change. Wrapping the handler will also break unwinding. It's +// still better than not adjusting at all.... +// +// This cannot be done when constructing the handler because NewLogr needs +// access to the original sink without this adjustment. A second copy would +// work, but then WithAttrs would have to be called for both of them. +func (l *slogHandler) sinkWithCallDepth() logr.LogSink { + if sink, ok := l.sink.(logr.CallDepthLogSink); ok { + return sink.WithCallDepth(2) + } + return l.sink +} + +func (l *slogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + if l.sink == nil || len(attrs) == 0 { + return l + } + + copy := *l + if l.slogSink != nil { + copy.slogSink = l.slogSink.WithAttrs(attrs) + copy.sink = copy.slogSink + } else { + kvList := make([]any, 0, 2*len(attrs)) + for _, attr := range attrs { + if attr.Key != "" { + kvList = append(kvList, l.addGroupPrefix(attr.Key), attr.Value.Resolve().Any()) + } + } + copy.sink = l.sink.WithValues(kvList...) + } + return © +} + +func (l *slogHandler) WithGroup(name string) slog.Handler { + if l.sink == nil { + return l + } + copy := *l + if l.slogSink != nil { + copy.slogSink = l.slogSink.WithGroup(name) + copy.sink = l.slogSink + } else { + copy.groupPrefix = copy.addGroupPrefix(name) + } + return © +} + +func (l *slogHandler) addGroupPrefix(name string) string { + if l.groupPrefix == "" { + return name + } + return l.groupPrefix + groupSeparator + name +} + +// levelFromSlog adjusts the level by the logger's verbosity and negates it. +// It ensures that the result is >= 0. This is necessary because the result is +// passed to a logr.LogSink and that API did not historically document whether +// levels could be negative or what that meant. +// +// Some example usage: +// logrV0 := getMyLogger() +// logrV2 := logrV0.V(2) +// slogV2 := slog.New(slogr.NewSlogHandler(logrV2)) +// slogV2.Debug("msg") // =~ logrV2.V(4) =~ logrV0.V(6) +// slogV2.Info("msg") // =~ logrV2.V(0) =~ logrV0.V(2) +// slogv2.Warn("msg") // =~ logrV2.V(-4) =~ logrV0.V(0) +func (l *slogHandler) levelFromSlog(level slog.Level) int { + result := -level + result += l.levelBias // in case the original logr.Logger had a V level + if result < 0 { + result = 0 // because logr.LogSink doesn't expect negative V levels + } + return int(result) +} diff --git a/vendor/github.com/go-logr/logr/slogr/slogr.go b/vendor/github.com/go-logr/logr/slogr/slogr.go new file mode 100644 index 0000000000..eb519ae23f --- /dev/null +++ b/vendor/github.com/go-logr/logr/slogr/slogr.go @@ -0,0 +1,108 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The logr Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package slogr enables usage of a slog.Handler with logr.Logger as front-end +// API and of a logr.LogSink through the slog.Handler and thus slog.Logger +// APIs. +// +// See the README in the top-level [./logr] package for a discussion of +// interoperability. +package slogr + +import ( + "context" + "log/slog" + + "github.com/go-logr/logr" +) + +// NewLogr returns a logr.Logger which writes to the slog.Handler. +// +// The logr verbosity level is mapped to slog levels such that V(0) becomes +// slog.LevelInfo and V(4) becomes slog.LevelDebug. +func NewLogr(handler slog.Handler) logr.Logger { + if handler, ok := handler.(*slogHandler); ok { + if handler.sink == nil { + return logr.Discard() + } + return logr.New(handler.sink).V(int(handler.levelBias)) + } + return logr.New(&slogSink{handler: handler}) +} + +// NewSlogHandler returns a slog.Handler which writes to the same sink as the logr.Logger. +// +// The returned logger writes all records with level >= slog.LevelError as +// error log entries with LogSink.Error, regardless of the verbosity level of +// the logr.Logger: +// +// logger := +// slog.New(NewSlogHandler(logger.V(10))).Error(...) -> logSink.Error(...) +// +// The level of all other records gets reduced by the verbosity +// level of the logr.Logger and the result is negated. If it happens +// to be negative, then it gets replaced by zero because a LogSink +// is not expected to handled negative levels: +// +// slog.New(NewSlogHandler(logger)).Debug(...) -> logger.GetSink().Info(level=4, ...) +// slog.New(NewSlogHandler(logger)).Warning(...) -> logger.GetSink().Info(level=0, ...) +// slog.New(NewSlogHandler(logger)).Info(...) -> logger.GetSink().Info(level=0, ...) +// slog.New(NewSlogHandler(logger.V(4))).Info(...) -> logger.GetSink().Info(level=4, ...) +func NewSlogHandler(logger logr.Logger) slog.Handler { + if sink, ok := logger.GetSink().(*slogSink); ok && logger.GetV() == 0 { + return sink.handler + } + + handler := &slogHandler{sink: logger.GetSink(), levelBias: slog.Level(logger.GetV())} + if slogSink, ok := handler.sink.(SlogSink); ok { + handler.slogSink = slogSink + } + return handler +} + +// SlogSink is an optional interface that a LogSink can implement to support +// logging through the slog.Logger or slog.Handler APIs better. It then should +// also support special slog values like slog.Group. When used as a +// slog.Handler, the advantages are: +// +// - stack unwinding gets avoided in favor of logging the pre-recorded PC, +// as intended by slog +// - proper grouping of key/value pairs via WithGroup +// - verbosity levels > slog.LevelInfo can be recorded +// - less overhead +// +// Both APIs (logr.Logger and slog.Logger/Handler) then are supported equally +// well. Developers can pick whatever API suits them better and/or mix +// packages which use either API in the same binary with a common logging +// implementation. +// +// This interface is necessary because the type implementing the LogSink +// interface cannot also implement the slog.Handler interface due to the +// different prototype of the common Enabled method. +// +// An implementation could support both interfaces in two different types, but then +// additional interfaces would be needed to convert between those types in NewLogr +// and NewSlogHandler. +type SlogSink interface { + logr.LogSink + + Handle(ctx context.Context, record slog.Record) error + WithAttrs(attrs []slog.Attr) SlogSink + WithGroup(name string) SlogSink +} diff --git a/vendor/github.com/go-logr/logr/slogr/slogsink.go b/vendor/github.com/go-logr/logr/slogr/slogsink.go new file mode 100644 index 0000000000..6fbac561d9 --- /dev/null +++ b/vendor/github.com/go-logr/logr/slogr/slogsink.go @@ -0,0 +1,122 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The logr Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package slogr + +import ( + "context" + "log/slog" + "runtime" + "time" + + "github.com/go-logr/logr" +) + +var ( + _ logr.LogSink = &slogSink{} + _ logr.CallDepthLogSink = &slogSink{} + _ Underlier = &slogSink{} +) + +// Underlier is implemented by the LogSink returned by NewLogr. +type Underlier interface { + // GetUnderlying returns the Handler used by the LogSink. + GetUnderlying() slog.Handler +} + +const ( + // nameKey is used to log the `WithName` values as an additional attribute. + nameKey = "logger" + + // errKey is used to log the error parameter of Error as an additional attribute. + errKey = "err" +) + +type slogSink struct { + callDepth int + name string + handler slog.Handler +} + +func (l *slogSink) Init(info logr.RuntimeInfo) { + l.callDepth = info.CallDepth +} + +func (l *slogSink) GetUnderlying() slog.Handler { + return l.handler +} + +func (l *slogSink) WithCallDepth(depth int) logr.LogSink { + newLogger := *l + newLogger.callDepth += depth + return &newLogger +} + +func (l *slogSink) Enabled(level int) bool { + return l.handler.Enabled(context.Background(), slog.Level(-level)) +} + +func (l *slogSink) Info(level int, msg string, kvList ...interface{}) { + l.log(nil, msg, slog.Level(-level), kvList...) +} + +func (l *slogSink) Error(err error, msg string, kvList ...interface{}) { + l.log(err, msg, slog.LevelError, kvList...) +} + +func (l *slogSink) log(err error, msg string, level slog.Level, kvList ...interface{}) { + var pcs [1]uintptr + // skip runtime.Callers, this function, Info/Error, and all helper functions above that. + runtime.Callers(3+l.callDepth, pcs[:]) + + record := slog.NewRecord(time.Now(), level, msg, pcs[0]) + if l.name != "" { + record.AddAttrs(slog.String(nameKey, l.name)) + } + if err != nil { + record.AddAttrs(slog.Any(errKey, err)) + } + record.Add(kvList...) + l.handler.Handle(context.Background(), record) +} + +func (l slogSink) WithName(name string) logr.LogSink { + if l.name != "" { + l.name = l.name + "/" + } + l.name += name + return &l +} + +func (l slogSink) WithValues(kvList ...interface{}) logr.LogSink { + l.handler = l.handler.WithAttrs(kvListToAttrs(kvList...)) + return &l +} + +func kvListToAttrs(kvList ...interface{}) []slog.Attr { + // We don't need the record itself, only its Add method. + record := slog.NewRecord(time.Time{}, 0, "", 0) + record.Add(kvList...) + attrs := make([]slog.Attr, 0, record.NumAttrs()) + record.Attrs(func(attr slog.Attr) bool { + attrs = append(attrs, attr) + return true + }) + return attrs +} diff --git a/vendor/github.com/go-ole/go-ole/.travis.yml b/vendor/github.com/go-ole/go-ole/.travis.yml new file mode 100644 index 0000000000..28f740cd5d --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/.travis.yml @@ -0,0 +1,8 @@ +language: go +sudo: false + +go: + - 1.9.x + - 1.10.x + - 1.11.x + - tip diff --git a/vendor/github.com/go-ole/go-ole/ChangeLog.md b/vendor/github.com/go-ole/go-ole/ChangeLog.md new file mode 100644 index 0000000000..4ba6a8c64d --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ChangeLog.md @@ -0,0 +1,49 @@ +# Version 1.x.x + +* **Add more test cases and reference new test COM server project.** (Placeholder for future additions) + +# Version 1.2.0-alphaX + +**Minimum supported version is now Go 1.4. Go 1.1 support is deprecated, but should still build.** + + * Added CI configuration for Travis-CI and AppVeyor. + * Added test InterfaceID and ClassID for the COM Test Server project. + * Added more inline documentation (#83). + * Added IEnumVARIANT implementation (#88). + * Added IEnumVARIANT test cases (#99, #100, #101). + * Added support for retrieving `time.Time` from VARIANT (#92). + * Added test case for IUnknown (#64). + * Added test case for IDispatch (#64). + * Added test cases for scalar variants (#64, #76). + +# Version 1.1.1 + + * Fixes for Linux build. + * Fixes for Windows build. + +# Version 1.1.0 + +The change to provide building on all platforms is a new feature. The increase in minor version reflects that and allows those who wish to stay on 1.0.x to continue to do so. Support for 1.0.x will be limited to bug fixes. + + * Move GUID out of variables.go into its own file to make new documentation available. + * Move OleError out of ole.go into its own file to make new documentation available. + * Add documentation to utility functions. + * Add documentation to variant receiver functions. + * Add documentation to ole structures. + * Make variant available to other systems outside of Windows. + * Make OLE structures available to other systems outside of Windows. + +## New Features + + * Library should now be built on all platforms supported by Go. Library will NOOP on any platform that is not Windows. + * More functions are now documented and available on godoc.org. + +# Version 1.0.1 + + 1. Fix package references from repository location change. + +# Version 1.0.0 + +This version is stable enough for use. The COM API is still incomplete, but provides enough functionality for accessing COM servers using IDispatch interface. + +There is no changelog for this version. Check commits for history. diff --git a/vendor/github.com/go-ole/go-ole/LICENSE b/vendor/github.com/go-ole/go-ole/LICENSE new file mode 100644 index 0000000000..623ec06f91 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright © 2013-2017 Yasuhiro Matsumoto, + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/go-ole/go-ole/README.md b/vendor/github.com/go-ole/go-ole/README.md new file mode 100644 index 0000000000..7b577558d1 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/README.md @@ -0,0 +1,46 @@ +# Go OLE + +[![Build status](https://ci.appveyor.com/api/projects/status/qr0u2sf7q43us9fj?svg=true)](https://ci.appveyor.com/project/jacobsantos/go-ole-jgs28) +[![Build Status](https://travis-ci.org/go-ole/go-ole.svg?branch=master)](https://travis-ci.org/go-ole/go-ole) +[![GoDoc](https://godoc.org/github.com/go-ole/go-ole?status.svg)](https://godoc.org/github.com/go-ole/go-ole) + +Go bindings for Windows COM using shared libraries instead of cgo. + +By Yasuhiro Matsumoto. + +## Install + +To experiment with go-ole, you can just compile and run the example program: + +``` +go get github.com/go-ole/go-ole +cd /path/to/go-ole/ +go test + +cd /path/to/go-ole/example/excel +go run excel.go +``` + +## Continuous Integration + +Continuous integration configuration has been added for both Travis-CI and AppVeyor. You will have to add these to your own account for your fork in order for it to run. + +**Travis-CI** + +Travis-CI was added to check builds on Linux to ensure that `go get` works when cross building. Currently, Travis-CI is not used to test cross-building, but this may be changed in the future. It is also not currently possible to test the library on Linux, since COM API is specific to Windows and it is not currently possible to run a COM server on Linux or even connect to a remote COM server. + +**AppVeyor** + +AppVeyor is used to build on Windows using the (in-development) test COM server. It is currently only used to test the build and ensure that the code works on Windows. It will be used to register a COM server and then run the test cases based on the test COM server. + +The tests currently do run and do pass and this should be maintained with commits. + +## Versioning + +Go OLE uses [semantic versioning](http://semver.org) for version numbers, which is similar to the version contract of the Go language. Which means that the major version will always maintain backwards compatibility with minor versions. Minor versions will only add new additions and changes. Fixes will always be in patch. + +This contract should allow you to upgrade to new minor and patch versions without breakage or modifications to your existing code. Leave a ticket, if there is breakage, so that it could be fixed. + +## LICENSE + +Under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/go-ole/go-ole/appveyor.yml b/vendor/github.com/go-ole/go-ole/appveyor.yml new file mode 100644 index 0000000000..0d557ac2ff --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/appveyor.yml @@ -0,0 +1,54 @@ +# Notes: +# - Minimal appveyor.yml file is an empty file. All sections are optional. +# - Indent each level of configuration with 2 spaces. Do not use tabs! +# - All section names are case-sensitive. +# - Section names should be unique on each level. + +version: "1.3.0.{build}-alpha-{branch}" + +os: Windows Server 2012 R2 + +branches: + only: + - master + - v1.2 + - v1.1 + - v1.0 + +skip_tags: true + +clone_folder: c:\gopath\src\github.com\go-ole\go-ole + +environment: + GOPATH: c:\gopath + matrix: + - GOARCH: amd64 + GOVERSION: 1.5 + GOROOT: c:\go + DOWNLOADPLATFORM: "x64" + +install: + - choco install mingw + - SET PATH=c:\tools\mingw64\bin;%PATH% + # - Download COM Server + - ps: Start-FileDownload "https://github.com/go-ole/test-com-server/releases/download/v1.0.2/test-com-server-${env:DOWNLOADPLATFORM}.zip" + - 7z e test-com-server-%DOWNLOADPLATFORM%.zip -oc:\gopath\src\github.com\go-ole\go-ole > NUL + - c:\gopath\src\github.com\go-ole\go-ole\build\register-assembly.bat + # - set + - go version + - go env + - go get -u golang.org/x/tools/cmd/cover + - go get -u golang.org/x/tools/cmd/godoc + - go get -u golang.org/x/tools/cmd/stringer + +build_script: + - cd c:\gopath\src\github.com\go-ole\go-ole + - go get -v -t ./... + - go build + - go test -v -cover ./... + +# disable automatic tests +test: off + +# disable deployment +deploy: off diff --git a/vendor/github.com/go-ole/go-ole/com.go b/vendor/github.com/go-ole/go-ole/com.go new file mode 100644 index 0000000000..a9bef150a3 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/com.go @@ -0,0 +1,344 @@ +// +build windows + +package ole + +import ( + "syscall" + "unicode/utf16" + "unsafe" +) + +var ( + procCoInitialize = modole32.NewProc("CoInitialize") + procCoInitializeEx = modole32.NewProc("CoInitializeEx") + procCoUninitialize = modole32.NewProc("CoUninitialize") + procCoCreateInstance = modole32.NewProc("CoCreateInstance") + procCoTaskMemFree = modole32.NewProc("CoTaskMemFree") + procCLSIDFromProgID = modole32.NewProc("CLSIDFromProgID") + procCLSIDFromString = modole32.NewProc("CLSIDFromString") + procStringFromCLSID = modole32.NewProc("StringFromCLSID") + procStringFromIID = modole32.NewProc("StringFromIID") + procIIDFromString = modole32.NewProc("IIDFromString") + procCoGetObject = modole32.NewProc("CoGetObject") + procGetUserDefaultLCID = modkernel32.NewProc("GetUserDefaultLCID") + procCopyMemory = modkernel32.NewProc("RtlMoveMemory") + procVariantInit = modoleaut32.NewProc("VariantInit") + procVariantClear = modoleaut32.NewProc("VariantClear") + procVariantTimeToSystemTime = modoleaut32.NewProc("VariantTimeToSystemTime") + procSysAllocString = modoleaut32.NewProc("SysAllocString") + procSysAllocStringLen = modoleaut32.NewProc("SysAllocStringLen") + procSysFreeString = modoleaut32.NewProc("SysFreeString") + procSysStringLen = modoleaut32.NewProc("SysStringLen") + procCreateDispTypeInfo = modoleaut32.NewProc("CreateDispTypeInfo") + procCreateStdDispatch = modoleaut32.NewProc("CreateStdDispatch") + procGetActiveObject = modoleaut32.NewProc("GetActiveObject") + + procGetMessageW = moduser32.NewProc("GetMessageW") + procDispatchMessageW = moduser32.NewProc("DispatchMessageW") +) + +// coInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). +func coInitialize() (err error) { + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms678543(v=vs.85).aspx + // Suggests that no value should be passed to CoInitialized. + // Could just be Call() since the parameter is optional. <-- Needs testing to be sure. + hr, _, _ := procCoInitialize.Call(uintptr(0)) + if hr != 0 { + err = NewError(hr) + } + return +} + +// coInitializeEx initializes COM library with concurrency model. +func coInitializeEx(coinit uint32) (err error) { + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms695279(v=vs.85).aspx + // Suggests that the first parameter is not only optional but should always be NULL. + hr, _, _ := procCoInitializeEx.Call(uintptr(0), uintptr(coinit)) + if hr != 0 { + err = NewError(hr) + } + return +} + +// CoInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). +func CoInitialize(p uintptr) (err error) { + // p is ignored and won't be used. + // Avoid any variable not used errors. + p = uintptr(0) + return coInitialize() +} + +// CoInitializeEx initializes COM library with concurrency model. +func CoInitializeEx(p uintptr, coinit uint32) (err error) { + // Avoid any variable not used errors. + p = uintptr(0) + return coInitializeEx(coinit) +} + +// CoUninitialize uninitializes COM Library. +func CoUninitialize() { + procCoUninitialize.Call() +} + +// CoTaskMemFree frees memory pointer. +func CoTaskMemFree(memptr uintptr) { + procCoTaskMemFree.Call(memptr) +} + +// CLSIDFromProgID retrieves Class Identifier with the given Program Identifier. +// +// The Programmatic Identifier must be registered, because it will be looked up +// in the Windows Registry. The registry entry has the following keys: CLSID, +// Insertable, Protocol and Shell +// (https://msdn.microsoft.com/en-us/library/dd542719(v=vs.85).aspx). +// +// programID identifies the class id with less precision and is not guaranteed +// to be unique. These are usually found in the registry under +// HKEY_LOCAL_MACHINE\SOFTWARE\Classes, usually with the format of +// "Program.Component.Version" with version being optional. +// +// CLSIDFromProgID in Windows API. +func CLSIDFromProgID(progId string) (clsid *GUID, err error) { + var guid GUID + lpszProgID := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId))) + hr, _, _ := procCLSIDFromProgID.Call(lpszProgID, uintptr(unsafe.Pointer(&guid))) + if hr != 0 { + err = NewError(hr) + } + clsid = &guid + return +} + +// CLSIDFromString retrieves Class ID from string representation. +// +// This is technically the string version of the GUID and will convert the +// string to object. +// +// CLSIDFromString in Windows API. +func CLSIDFromString(str string) (clsid *GUID, err error) { + var guid GUID + lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) + hr, _, _ := procCLSIDFromString.Call(lpsz, uintptr(unsafe.Pointer(&guid))) + if hr != 0 { + err = NewError(hr) + } + clsid = &guid + return +} + +// StringFromCLSID returns GUID formated string from GUID object. +func StringFromCLSID(clsid *GUID) (str string, err error) { + var p *uint16 + hr, _, _ := procStringFromCLSID.Call(uintptr(unsafe.Pointer(clsid)), uintptr(unsafe.Pointer(&p))) + if hr != 0 { + err = NewError(hr) + } + str = LpOleStrToString(p) + return +} + +// IIDFromString returns GUID from program ID. +func IIDFromString(progId string) (clsid *GUID, err error) { + var guid GUID + lpsz := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(progId))) + hr, _, _ := procIIDFromString.Call(lpsz, uintptr(unsafe.Pointer(&guid))) + if hr != 0 { + err = NewError(hr) + } + clsid = &guid + return +} + +// StringFromIID returns GUID formatted string from GUID object. +func StringFromIID(iid *GUID) (str string, err error) { + var p *uint16 + hr, _, _ := procStringFromIID.Call(uintptr(unsafe.Pointer(iid)), uintptr(unsafe.Pointer(&p))) + if hr != 0 { + err = NewError(hr) + } + str = LpOleStrToString(p) + return +} + +// CreateInstance of single uninitialized object with GUID. +func CreateInstance(clsid *GUID, iid *GUID) (unk *IUnknown, err error) { + if iid == nil { + iid = IID_IUnknown + } + hr, _, _ := procCoCreateInstance.Call( + uintptr(unsafe.Pointer(clsid)), + 0, + CLSCTX_SERVER, + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(&unk))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// GetActiveObject retrieves pointer to active object. +func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) { + if iid == nil { + iid = IID_IUnknown + } + hr, _, _ := procGetActiveObject.Call( + uintptr(unsafe.Pointer(clsid)), + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(&unk))) + if hr != 0 { + err = NewError(hr) + } + return +} + +type BindOpts struct { + CbStruct uint32 + GrfFlags uint32 + GrfMode uint32 + TickCountDeadline uint32 +} + +// GetObject retrieves pointer to active object. +func GetObject(programID string, bindOpts *BindOpts, iid *GUID) (unk *IUnknown, err error) { + if bindOpts != nil { + bindOpts.CbStruct = uint32(unsafe.Sizeof(BindOpts{})) + } + if iid == nil { + iid = IID_IUnknown + } + hr, _, _ := procCoGetObject.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(programID))), + uintptr(unsafe.Pointer(bindOpts)), + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(&unk))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// VariantInit initializes variant. +func VariantInit(v *VARIANT) (err error) { + hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// VariantClear clears value in Variant settings to VT_EMPTY. +func VariantClear(v *VARIANT) (err error) { + hr, _, _ := procVariantClear.Call(uintptr(unsafe.Pointer(v))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// SysAllocString allocates memory for string and copies string into memory. +func SysAllocString(v string) (ss *int16) { + pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v)))) + ss = (*int16)(unsafe.Pointer(pss)) + return +} + +// SysAllocStringLen copies up to length of given string returning pointer. +func SysAllocStringLen(v string) (ss *int16) { + utf16 := utf16.Encode([]rune(v + "\x00")) + ptr := &utf16[0] + + pss, _, _ := procSysAllocStringLen.Call(uintptr(unsafe.Pointer(ptr)), uintptr(len(utf16)-1)) + ss = (*int16)(unsafe.Pointer(pss)) + return +} + +// SysFreeString frees string system memory. This must be called with SysAllocString. +func SysFreeString(v *int16) (err error) { + hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// SysStringLen is the length of the system allocated string. +func SysStringLen(v *int16) uint32 { + l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v))) + return uint32(l) +} + +// CreateStdDispatch provides default IDispatch implementation for IUnknown. +// +// This handles default IDispatch implementation for objects. It haves a few +// limitations with only supporting one language. It will also only return +// default exception codes. +func CreateStdDispatch(unk *IUnknown, v uintptr, ptinfo *IUnknown) (disp *IDispatch, err error) { + hr, _, _ := procCreateStdDispatch.Call( + uintptr(unsafe.Pointer(unk)), + v, + uintptr(unsafe.Pointer(ptinfo)), + uintptr(unsafe.Pointer(&disp))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// CreateDispTypeInfo provides default ITypeInfo implementation for IDispatch. +// +// This will not handle the full implementation of the interface. +func CreateDispTypeInfo(idata *INTERFACEDATA) (pptinfo *IUnknown, err error) { + hr, _, _ := procCreateDispTypeInfo.Call( + uintptr(unsafe.Pointer(idata)), + uintptr(GetUserDefaultLCID()), + uintptr(unsafe.Pointer(&pptinfo))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// copyMemory moves location of a block of memory. +func copyMemory(dest unsafe.Pointer, src unsafe.Pointer, length uint32) { + procCopyMemory.Call(uintptr(dest), uintptr(src), uintptr(length)) +} + +// GetUserDefaultLCID retrieves current user default locale. +func GetUserDefaultLCID() (lcid uint32) { + ret, _, _ := procGetUserDefaultLCID.Call() + lcid = uint32(ret) + return +} + +// GetMessage in message queue from runtime. +// +// This function appears to block. PeekMessage does not block. +func GetMessage(msg *Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) { + r0, _, err := procGetMessageW.Call(uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax)) + ret = int32(r0) + return +} + +// DispatchMessage to window procedure. +func DispatchMessage(msg *Msg) (ret int32) { + r0, _, _ := procDispatchMessageW.Call(uintptr(unsafe.Pointer(msg))) + ret = int32(r0) + return +} diff --git a/vendor/github.com/go-ole/go-ole/com_func.go b/vendor/github.com/go-ole/go-ole/com_func.go new file mode 100644 index 0000000000..cef539d9dd --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/com_func.go @@ -0,0 +1,174 @@ +// +build !windows + +package ole + +import ( + "time" + "unsafe" +) + +// coInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). +func coInitialize() error { + return NewError(E_NOTIMPL) +} + +// coInitializeEx initializes COM library with concurrency model. +func coInitializeEx(coinit uint32) error { + return NewError(E_NOTIMPL) +} + +// CoInitialize initializes COM library on current thread. +// +// MSDN documentation suggests that this function should not be called. Call +// CoInitializeEx() instead. The reason has to do with threading and this +// function is only for single-threaded apartments. +// +// That said, most users of the library have gotten away with just this +// function. If you are experiencing threading issues, then use +// CoInitializeEx(). +func CoInitialize(p uintptr) error { + return NewError(E_NOTIMPL) +} + +// CoInitializeEx initializes COM library with concurrency model. +func CoInitializeEx(p uintptr, coinit uint32) error { + return NewError(E_NOTIMPL) +} + +// CoUninitialize uninitializes COM Library. +func CoUninitialize() {} + +// CoTaskMemFree frees memory pointer. +func CoTaskMemFree(memptr uintptr) {} + +// CLSIDFromProgID retrieves Class Identifier with the given Program Identifier. +// +// The Programmatic Identifier must be registered, because it will be looked up +// in the Windows Registry. The registry entry has the following keys: CLSID, +// Insertable, Protocol and Shell +// (https://msdn.microsoft.com/en-us/library/dd542719(v=vs.85).aspx). +// +// programID identifies the class id with less precision and is not guaranteed +// to be unique. These are usually found in the registry under +// HKEY_LOCAL_MACHINE\SOFTWARE\Classes, usually with the format of +// "Program.Component.Version" with version being optional. +// +// CLSIDFromProgID in Windows API. +func CLSIDFromProgID(progId string) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// CLSIDFromString retrieves Class ID from string representation. +// +// This is technically the string version of the GUID and will convert the +// string to object. +// +// CLSIDFromString in Windows API. +func CLSIDFromString(str string) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// StringFromCLSID returns GUID formated string from GUID object. +func StringFromCLSID(clsid *GUID) (string, error) { + return "", NewError(E_NOTIMPL) +} + +// IIDFromString returns GUID from program ID. +func IIDFromString(progId string) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// StringFromIID returns GUID formatted string from GUID object. +func StringFromIID(iid *GUID) (string, error) { + return "", NewError(E_NOTIMPL) +} + +// CreateInstance of single uninitialized object with GUID. +func CreateInstance(clsid *GUID, iid *GUID) (*IUnknown, error) { + return nil, NewError(E_NOTIMPL) +} + +// GetActiveObject retrieves pointer to active object. +func GetActiveObject(clsid *GUID, iid *GUID) (*IUnknown, error) { + return nil, NewError(E_NOTIMPL) +} + +// VariantInit initializes variant. +func VariantInit(v *VARIANT) error { + return NewError(E_NOTIMPL) +} + +// VariantClear clears value in Variant settings to VT_EMPTY. +func VariantClear(v *VARIANT) error { + return NewError(E_NOTIMPL) +} + +// SysAllocString allocates memory for string and copies string into memory. +func SysAllocString(v string) *int16 { + u := int16(0) + return &u +} + +// SysAllocStringLen copies up to length of given string returning pointer. +func SysAllocStringLen(v string) *int16 { + u := int16(0) + return &u +} + +// SysFreeString frees string system memory. This must be called with SysAllocString. +func SysFreeString(v *int16) error { + return NewError(E_NOTIMPL) +} + +// SysStringLen is the length of the system allocated string. +func SysStringLen(v *int16) uint32 { + return uint32(0) +} + +// CreateStdDispatch provides default IDispatch implementation for IUnknown. +// +// This handles default IDispatch implementation for objects. It haves a few +// limitations with only supporting one language. It will also only return +// default exception codes. +func CreateStdDispatch(unk *IUnknown, v uintptr, ptinfo *IUnknown) (*IDispatch, error) { + return nil, NewError(E_NOTIMPL) +} + +// CreateDispTypeInfo provides default ITypeInfo implementation for IDispatch. +// +// This will not handle the full implementation of the interface. +func CreateDispTypeInfo(idata *INTERFACEDATA) (*IUnknown, error) { + return nil, NewError(E_NOTIMPL) +} + +// copyMemory moves location of a block of memory. +func copyMemory(dest unsafe.Pointer, src unsafe.Pointer, length uint32) {} + +// GetUserDefaultLCID retrieves current user default locale. +func GetUserDefaultLCID() uint32 { + return uint32(0) +} + +// GetMessage in message queue from runtime. +// +// This function appears to block. PeekMessage does not block. +func GetMessage(msg *Msg, hwnd uint32, MsgFilterMin uint32, MsgFilterMax uint32) (int32, error) { + return int32(0), NewError(E_NOTIMPL) +} + +// DispatchMessage to window procedure. +func DispatchMessage(msg *Msg) int32 { + return int32(0) +} + +func GetVariantDate(value uint64) (time.Time, error) { + return time.Now(), NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/connect.go b/vendor/github.com/go-ole/go-ole/connect.go new file mode 100644 index 0000000000..b2ac2ec67a --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/connect.go @@ -0,0 +1,192 @@ +package ole + +// Connection contains IUnknown for fluent interface interaction. +// +// Deprecated. Use oleutil package instead. +type Connection struct { + Object *IUnknown // Access COM +} + +// Initialize COM. +func (*Connection) Initialize() (err error) { + return coInitialize() +} + +// Uninitialize COM. +func (*Connection) Uninitialize() { + CoUninitialize() +} + +// Create IUnknown object based first on ProgId and then from String. +func (c *Connection) Create(progId string) (err error) { + var clsid *GUID + clsid, err = CLSIDFromProgID(progId) + if err != nil { + clsid, err = CLSIDFromString(progId) + if err != nil { + return + } + } + + unknown, err := CreateInstance(clsid, IID_IUnknown) + if err != nil { + return + } + c.Object = unknown + + return +} + +// Release IUnknown object. +func (c *Connection) Release() { + c.Object.Release() +} + +// Load COM object from list of programIDs or strings. +func (c *Connection) Load(names ...string) (errors []error) { + var tempErrors []error = make([]error, len(names)) + var numErrors int = 0 + for _, name := range names { + err := c.Create(name) + if err != nil { + tempErrors = append(tempErrors, err) + numErrors += 1 + continue + } + break + } + + copy(errors, tempErrors[0:numErrors]) + return +} + +// Dispatch returns Dispatch object. +func (c *Connection) Dispatch() (object *Dispatch, err error) { + dispatch, err := c.Object.QueryInterface(IID_IDispatch) + if err != nil { + return + } + object = &Dispatch{dispatch} + return +} + +// Dispatch stores IDispatch object. +type Dispatch struct { + Object *IDispatch // Dispatch object. +} + +// Call method on IDispatch with parameters. +func (d *Dispatch) Call(method string, params ...interface{}) (result *VARIANT, err error) { + id, err := d.GetId(method) + if err != nil { + return + } + + result, err = d.Invoke(id, DISPATCH_METHOD, params) + return +} + +// MustCall method on IDispatch with parameters. +func (d *Dispatch) MustCall(method string, params ...interface{}) (result *VARIANT) { + id, err := d.GetId(method) + if err != nil { + panic(err) + } + + result, err = d.Invoke(id, DISPATCH_METHOD, params) + if err != nil { + panic(err) + } + + return +} + +// Get property on IDispatch with parameters. +func (d *Dispatch) Get(name string, params ...interface{}) (result *VARIANT, err error) { + id, err := d.GetId(name) + if err != nil { + return + } + result, err = d.Invoke(id, DISPATCH_PROPERTYGET, params) + return +} + +// MustGet property on IDispatch with parameters. +func (d *Dispatch) MustGet(name string, params ...interface{}) (result *VARIANT) { + id, err := d.GetId(name) + if err != nil { + panic(err) + } + + result, err = d.Invoke(id, DISPATCH_PROPERTYGET, params) + if err != nil { + panic(err) + } + return +} + +// Set property on IDispatch with parameters. +func (d *Dispatch) Set(name string, params ...interface{}) (result *VARIANT, err error) { + id, err := d.GetId(name) + if err != nil { + return + } + result, err = d.Invoke(id, DISPATCH_PROPERTYPUT, params) + return +} + +// MustSet property on IDispatch with parameters. +func (d *Dispatch) MustSet(name string, params ...interface{}) (result *VARIANT) { + id, err := d.GetId(name) + if err != nil { + panic(err) + } + + result, err = d.Invoke(id, DISPATCH_PROPERTYPUT, params) + if err != nil { + panic(err) + } + return +} + +// GetId retrieves ID of name on IDispatch. +func (d *Dispatch) GetId(name string) (id int32, err error) { + var dispid []int32 + dispid, err = d.Object.GetIDsOfName([]string{name}) + if err != nil { + return + } + id = dispid[0] + return +} + +// GetIds retrieves all IDs of names on IDispatch. +func (d *Dispatch) GetIds(names ...string) (dispid []int32, err error) { + dispid, err = d.Object.GetIDsOfName(names) + return +} + +// Invoke IDispatch on DisplayID of dispatch type with parameters. +// +// There have been problems where if send cascading params..., it would error +// out because the parameters would be empty. +func (d *Dispatch) Invoke(id int32, dispatch int16, params []interface{}) (result *VARIANT, err error) { + if len(params) < 1 { + result, err = d.Object.Invoke(id, dispatch) + } else { + result, err = d.Object.Invoke(id, dispatch, params...) + } + return +} + +// Release IDispatch object. +func (d *Dispatch) Release() { + d.Object.Release() +} + +// Connect initializes COM and attempts to load IUnknown based on given names. +func Connect(names ...string) (connection *Connection) { + connection.Initialize() + connection.Load(names...) + return +} diff --git a/vendor/github.com/go-ole/go-ole/constants.go b/vendor/github.com/go-ole/go-ole/constants.go new file mode 100644 index 0000000000..fd0c6d74b0 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/constants.go @@ -0,0 +1,153 @@ +package ole + +const ( + CLSCTX_INPROC_SERVER = 1 + CLSCTX_INPROC_HANDLER = 2 + CLSCTX_LOCAL_SERVER = 4 + CLSCTX_INPROC_SERVER16 = 8 + CLSCTX_REMOTE_SERVER = 16 + CLSCTX_ALL = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER + CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER + CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER +) + +const ( + COINIT_APARTMENTTHREADED = 0x2 + COINIT_MULTITHREADED = 0x0 + COINIT_DISABLE_OLE1DDE = 0x4 + COINIT_SPEED_OVER_MEMORY = 0x8 +) + +const ( + DISPATCH_METHOD = 1 + DISPATCH_PROPERTYGET = 2 + DISPATCH_PROPERTYPUT = 4 + DISPATCH_PROPERTYPUTREF = 8 +) + +const ( + S_OK = 0x00000000 + E_UNEXPECTED = 0x8000FFFF + E_NOTIMPL = 0x80004001 + E_OUTOFMEMORY = 0x8007000E + E_INVALIDARG = 0x80070057 + E_NOINTERFACE = 0x80004002 + E_POINTER = 0x80004003 + E_HANDLE = 0x80070006 + E_ABORT = 0x80004004 + E_FAIL = 0x80004005 + E_ACCESSDENIED = 0x80070005 + E_PENDING = 0x8000000A + + CO_E_CLASSSTRING = 0x800401F3 +) + +const ( + CC_FASTCALL = iota + CC_CDECL + CC_MSCPASCAL + CC_PASCAL = CC_MSCPASCAL + CC_MACPASCAL + CC_STDCALL + CC_FPFASTCALL + CC_SYSCALL + CC_MPWCDECL + CC_MPWPASCAL + CC_MAX = CC_MPWPASCAL +) + +type VT uint16 + +const ( + VT_EMPTY VT = 0x0 + VT_NULL VT = 0x1 + VT_I2 VT = 0x2 + VT_I4 VT = 0x3 + VT_R4 VT = 0x4 + VT_R8 VT = 0x5 + VT_CY VT = 0x6 + VT_DATE VT = 0x7 + VT_BSTR VT = 0x8 + VT_DISPATCH VT = 0x9 + VT_ERROR VT = 0xa + VT_BOOL VT = 0xb + VT_VARIANT VT = 0xc + VT_UNKNOWN VT = 0xd + VT_DECIMAL VT = 0xe + VT_I1 VT = 0x10 + VT_UI1 VT = 0x11 + VT_UI2 VT = 0x12 + VT_UI4 VT = 0x13 + VT_I8 VT = 0x14 + VT_UI8 VT = 0x15 + VT_INT VT = 0x16 + VT_UINT VT = 0x17 + VT_VOID VT = 0x18 + VT_HRESULT VT = 0x19 + VT_PTR VT = 0x1a + VT_SAFEARRAY VT = 0x1b + VT_CARRAY VT = 0x1c + VT_USERDEFINED VT = 0x1d + VT_LPSTR VT = 0x1e + VT_LPWSTR VT = 0x1f + VT_RECORD VT = 0x24 + VT_INT_PTR VT = 0x25 + VT_UINT_PTR VT = 0x26 + VT_FILETIME VT = 0x40 + VT_BLOB VT = 0x41 + VT_STREAM VT = 0x42 + VT_STORAGE VT = 0x43 + VT_STREAMED_OBJECT VT = 0x44 + VT_STORED_OBJECT VT = 0x45 + VT_BLOB_OBJECT VT = 0x46 + VT_CF VT = 0x47 + VT_CLSID VT = 0x48 + VT_BSTR_BLOB VT = 0xfff + VT_VECTOR VT = 0x1000 + VT_ARRAY VT = 0x2000 + VT_BYREF VT = 0x4000 + VT_RESERVED VT = 0x8000 + VT_ILLEGAL VT = 0xffff + VT_ILLEGALMASKED VT = 0xfff + VT_TYPEMASK VT = 0xfff +) + +const ( + DISPID_UNKNOWN = -1 + DISPID_VALUE = 0 + DISPID_PROPERTYPUT = -3 + DISPID_NEWENUM = -4 + DISPID_EVALUATE = -5 + DISPID_CONSTRUCTOR = -6 + DISPID_DESTRUCTOR = -7 + DISPID_COLLECT = -8 +) + +const ( + TKIND_ENUM = 1 + TKIND_RECORD = 2 + TKIND_MODULE = 3 + TKIND_INTERFACE = 4 + TKIND_DISPATCH = 5 + TKIND_COCLASS = 6 + TKIND_ALIAS = 7 + TKIND_UNION = 8 + TKIND_MAX = 9 +) + +// Safe Array Feature Flags + +const ( + FADF_AUTO = 0x0001 + FADF_STATIC = 0x0002 + FADF_EMBEDDED = 0x0004 + FADF_FIXEDSIZE = 0x0010 + FADF_RECORD = 0x0020 + FADF_HAVEIID = 0x0040 + FADF_HAVEVARTYPE = 0x0080 + FADF_BSTR = 0x0100 + FADF_UNKNOWN = 0x0200 + FADF_DISPATCH = 0x0400 + FADF_VARIANT = 0x0800 + FADF_RESERVED = 0xF008 +) diff --git a/vendor/github.com/go-ole/go-ole/error.go b/vendor/github.com/go-ole/go-ole/error.go new file mode 100644 index 0000000000..096b456d3a --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/error.go @@ -0,0 +1,51 @@ +package ole + +// OleError stores COM errors. +type OleError struct { + hr uintptr + description string + subError error +} + +// NewError creates new error with HResult. +func NewError(hr uintptr) *OleError { + return &OleError{hr: hr} +} + +// NewErrorWithDescription creates new COM error with HResult and description. +func NewErrorWithDescription(hr uintptr, description string) *OleError { + return &OleError{hr: hr, description: description} +} + +// NewErrorWithSubError creates new COM error with parent error. +func NewErrorWithSubError(hr uintptr, description string, err error) *OleError { + return &OleError{hr: hr, description: description, subError: err} +} + +// Code is the HResult. +func (v *OleError) Code() uintptr { + return uintptr(v.hr) +} + +// String description, either manually set or format message with error code. +func (v *OleError) String() string { + if v.description != "" { + return errstr(int(v.hr)) + " (" + v.description + ")" + } + return errstr(int(v.hr)) +} + +// Error implements error interface. +func (v *OleError) Error() string { + return v.String() +} + +// Description retrieves error summary, if there is one. +func (v *OleError) Description() string { + return v.description +} + +// SubError returns parent error, if there is one. +func (v *OleError) SubError() error { + return v.subError +} diff --git a/vendor/github.com/go-ole/go-ole/error_func.go b/vendor/github.com/go-ole/go-ole/error_func.go new file mode 100644 index 0000000000..8a2ffaa272 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/error_func.go @@ -0,0 +1,8 @@ +// +build !windows + +package ole + +// errstr converts error code to string. +func errstr(errno int) string { + return "" +} diff --git a/vendor/github.com/go-ole/go-ole/error_windows.go b/vendor/github.com/go-ole/go-ole/error_windows.go new file mode 100644 index 0000000000..d0e8e68595 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/error_windows.go @@ -0,0 +1,24 @@ +// +build windows + +package ole + +import ( + "fmt" + "syscall" + "unicode/utf16" +) + +// errstr converts error code to string. +func errstr(errno int) string { + // ask windows for the remaining errors + var flags uint32 = syscall.FORMAT_MESSAGE_FROM_SYSTEM | syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY | syscall.FORMAT_MESSAGE_IGNORE_INSERTS + b := make([]uint16, 300) + n, err := syscall.FormatMessage(flags, 0, uint32(errno), 0, b, nil) + if err != nil { + return fmt.Sprintf("error %d (FormatMessage failed with: %v)", errno, err) + } + // trim terminating \r and \n + for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { + } + return string(utf16.Decode(b[:n])) +} diff --git a/vendor/github.com/go-ole/go-ole/guid.go b/vendor/github.com/go-ole/go-ole/guid.go new file mode 100644 index 0000000000..8d20f68fbf --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/guid.go @@ -0,0 +1,284 @@ +package ole + +var ( + // IID_NULL is null Interface ID, used when no other Interface ID is known. + IID_NULL = NewGUID("{00000000-0000-0000-0000-000000000000}") + + // IID_IUnknown is for IUnknown interfaces. + IID_IUnknown = NewGUID("{00000000-0000-0000-C000-000000000046}") + + // IID_IDispatch is for IDispatch interfaces. + IID_IDispatch = NewGUID("{00020400-0000-0000-C000-000000000046}") + + // IID_IEnumVariant is for IEnumVariant interfaces + IID_IEnumVariant = NewGUID("{00020404-0000-0000-C000-000000000046}") + + // IID_IConnectionPointContainer is for IConnectionPointContainer interfaces. + IID_IConnectionPointContainer = NewGUID("{B196B284-BAB4-101A-B69C-00AA00341D07}") + + // IID_IConnectionPoint is for IConnectionPoint interfaces. + IID_IConnectionPoint = NewGUID("{B196B286-BAB4-101A-B69C-00AA00341D07}") + + // IID_IInspectable is for IInspectable interfaces. + IID_IInspectable = NewGUID("{AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}") + + // IID_IProvideClassInfo is for IProvideClassInfo interfaces. + IID_IProvideClassInfo = NewGUID("{B196B283-BAB4-101A-B69C-00AA00341D07}") +) + +// These are for testing and not part of any library. +var ( + // IID_ICOMTestString is for ICOMTestString interfaces. + // + // {E0133EB4-C36F-469A-9D3D-C66B84BE19ED} + IID_ICOMTestString = NewGUID("{E0133EB4-C36F-469A-9D3D-C66B84BE19ED}") + + // IID_ICOMTestInt8 is for ICOMTestInt8 interfaces. + // + // {BEB06610-EB84-4155-AF58-E2BFF53680B4} + IID_ICOMTestInt8 = NewGUID("{BEB06610-EB84-4155-AF58-E2BFF53680B4}") + + // IID_ICOMTestInt16 is for ICOMTestInt16 interfaces. + // + // {DAA3F9FA-761E-4976-A860-8364CE55F6FC} + IID_ICOMTestInt16 = NewGUID("{DAA3F9FA-761E-4976-A860-8364CE55F6FC}") + + // IID_ICOMTestInt32 is for ICOMTestInt32 interfaces. + // + // {E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0} + IID_ICOMTestInt32 = NewGUID("{E3DEDEE7-38A2-4540-91D1-2EEF1D8891B0}") + + // IID_ICOMTestInt64 is for ICOMTestInt64 interfaces. + // + // {8D437CBC-B3ED-485C-BC32-C336432A1623} + IID_ICOMTestInt64 = NewGUID("{8D437CBC-B3ED-485C-BC32-C336432A1623}") + + // IID_ICOMTestFloat is for ICOMTestFloat interfaces. + // + // {BF1ED004-EA02-456A-AA55-2AC8AC6B054C} + IID_ICOMTestFloat = NewGUID("{BF1ED004-EA02-456A-AA55-2AC8AC6B054C}") + + // IID_ICOMTestDouble is for ICOMTestDouble interfaces. + // + // {BF908A81-8687-4E93-999F-D86FAB284BA0} + IID_ICOMTestDouble = NewGUID("{BF908A81-8687-4E93-999F-D86FAB284BA0}") + + // IID_ICOMTestBoolean is for ICOMTestBoolean interfaces. + // + // {D530E7A6-4EE8-40D1-8931-3D63B8605010} + IID_ICOMTestBoolean = NewGUID("{D530E7A6-4EE8-40D1-8931-3D63B8605010}") + + // IID_ICOMEchoTestObject is for ICOMEchoTestObject interfaces. + // + // {6485B1EF-D780-4834-A4FE-1EBB51746CA3} + IID_ICOMEchoTestObject = NewGUID("{6485B1EF-D780-4834-A4FE-1EBB51746CA3}") + + // IID_ICOMTestTypes is for ICOMTestTypes interfaces. + // + // {CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0} + IID_ICOMTestTypes = NewGUID("{CCA8D7AE-91C0-4277-A8B3-FF4EDF28D3C0}") + + // CLSID_COMEchoTestObject is for COMEchoTestObject class. + // + // {3C24506A-AE9E-4D50-9157-EF317281F1B0} + CLSID_COMEchoTestObject = NewGUID("{3C24506A-AE9E-4D50-9157-EF317281F1B0}") + + // CLSID_COMTestScalarClass is for COMTestScalarClass class. + // + // {865B85C5-0334-4AC6-9EF6-AACEC8FC5E86} + CLSID_COMTestScalarClass = NewGUID("{865B85C5-0334-4AC6-9EF6-AACEC8FC5E86}") +) + +const hextable = "0123456789ABCDEF" +const emptyGUID = "{00000000-0000-0000-0000-000000000000}" + +// GUID is Windows API specific GUID type. +// +// This exists to match Windows GUID type for direct passing for COM. +// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx. +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +// NewGUID converts the given string into a globally unique identifier that is +// compliant with the Windows API. +// +// The supplied string may be in any of these formats: +// +// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX +// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} +// +// The conversion of the supplied string is not case-sensitive. +func NewGUID(guid string) *GUID { + d := []byte(guid) + var d1, d2, d3, d4a, d4b []byte + + switch len(d) { + case 38: + if d[0] != '{' || d[37] != '}' { + return nil + } + d = d[1:37] + fallthrough + case 36: + if d[8] != '-' || d[13] != '-' || d[18] != '-' || d[23] != '-' { + return nil + } + d1 = d[0:8] + d2 = d[9:13] + d3 = d[14:18] + d4a = d[19:23] + d4b = d[24:36] + case 32: + d1 = d[0:8] + d2 = d[8:12] + d3 = d[12:16] + d4a = d[16:20] + d4b = d[20:32] + default: + return nil + } + + var g GUID + var ok1, ok2, ok3, ok4 bool + g.Data1, ok1 = decodeHexUint32(d1) + g.Data2, ok2 = decodeHexUint16(d2) + g.Data3, ok3 = decodeHexUint16(d3) + g.Data4, ok4 = decodeHexByte64(d4a, d4b) + if ok1 && ok2 && ok3 && ok4 { + return &g + } + return nil +} + +func decodeHexUint32(src []byte) (value uint32, ok bool) { + var b1, b2, b3, b4 byte + var ok1, ok2, ok3, ok4 bool + b1, ok1 = decodeHexByte(src[0], src[1]) + b2, ok2 = decodeHexByte(src[2], src[3]) + b3, ok3 = decodeHexByte(src[4], src[5]) + b4, ok4 = decodeHexByte(src[6], src[7]) + value = (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4) + ok = ok1 && ok2 && ok3 && ok4 + return +} + +func decodeHexUint16(src []byte) (value uint16, ok bool) { + var b1, b2 byte + var ok1, ok2 bool + b1, ok1 = decodeHexByte(src[0], src[1]) + b2, ok2 = decodeHexByte(src[2], src[3]) + value = (uint16(b1) << 8) | uint16(b2) + ok = ok1 && ok2 + return +} + +func decodeHexByte64(s1 []byte, s2 []byte) (value [8]byte, ok bool) { + var ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8 bool + value[0], ok1 = decodeHexByte(s1[0], s1[1]) + value[1], ok2 = decodeHexByte(s1[2], s1[3]) + value[2], ok3 = decodeHexByte(s2[0], s2[1]) + value[3], ok4 = decodeHexByte(s2[2], s2[3]) + value[4], ok5 = decodeHexByte(s2[4], s2[5]) + value[5], ok6 = decodeHexByte(s2[6], s2[7]) + value[6], ok7 = decodeHexByte(s2[8], s2[9]) + value[7], ok8 = decodeHexByte(s2[10], s2[11]) + ok = ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8 + return +} + +func decodeHexByte(c1, c2 byte) (value byte, ok bool) { + var n1, n2 byte + var ok1, ok2 bool + n1, ok1 = decodeHexChar(c1) + n2, ok2 = decodeHexChar(c2) + value = (n1 << 4) | n2 + ok = ok1 && ok2 + return +} + +func decodeHexChar(c byte) (byte, bool) { + switch { + case '0' <= c && c <= '9': + return c - '0', true + case 'a' <= c && c <= 'f': + return c - 'a' + 10, true + case 'A' <= c && c <= 'F': + return c - 'A' + 10, true + } + + return 0, false +} + +// String converts the GUID to string form. It will adhere to this pattern: +// +// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} +// +// If the GUID is nil, the string representation of an empty GUID is returned: +// +// {00000000-0000-0000-0000-000000000000} +func (guid *GUID) String() string { + if guid == nil { + return emptyGUID + } + + var c [38]byte + c[0] = '{' + putUint32Hex(c[1:9], guid.Data1) + c[9] = '-' + putUint16Hex(c[10:14], guid.Data2) + c[14] = '-' + putUint16Hex(c[15:19], guid.Data3) + c[19] = '-' + putByteHex(c[20:24], guid.Data4[0:2]) + c[24] = '-' + putByteHex(c[25:37], guid.Data4[2:8]) + c[37] = '}' + return string(c[:]) +} + +func putUint32Hex(b []byte, v uint32) { + b[0] = hextable[byte(v>>24)>>4] + b[1] = hextable[byte(v>>24)&0x0f] + b[2] = hextable[byte(v>>16)>>4] + b[3] = hextable[byte(v>>16)&0x0f] + b[4] = hextable[byte(v>>8)>>4] + b[5] = hextable[byte(v>>8)&0x0f] + b[6] = hextable[byte(v)>>4] + b[7] = hextable[byte(v)&0x0f] +} + +func putUint16Hex(b []byte, v uint16) { + b[0] = hextable[byte(v>>8)>>4] + b[1] = hextable[byte(v>>8)&0x0f] + b[2] = hextable[byte(v)>>4] + b[3] = hextable[byte(v)&0x0f] +} + +func putByteHex(dst, src []byte) { + for i := 0; i < len(src); i++ { + dst[i*2] = hextable[src[i]>>4] + dst[i*2+1] = hextable[src[i]&0x0f] + } +} + +// IsEqualGUID compares two GUID. +// +// Not constant time comparison. +func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool { + return guid1.Data1 == guid2.Data1 && + guid1.Data2 == guid2.Data2 && + guid1.Data3 == guid2.Data3 && + guid1.Data4[0] == guid2.Data4[0] && + guid1.Data4[1] == guid2.Data4[1] && + guid1.Data4[2] == guid2.Data4[2] && + guid1.Data4[3] == guid2.Data4[3] && + guid1.Data4[4] == guid2.Data4[4] && + guid1.Data4[5] == guid2.Data4[5] && + guid1.Data4[6] == guid2.Data4[6] && + guid1.Data4[7] == guid2.Data4[7] +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpoint.go b/vendor/github.com/go-ole/go-ole/iconnectionpoint.go new file mode 100644 index 0000000000..9e6c49f41f --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpoint.go @@ -0,0 +1,20 @@ +package ole + +import "unsafe" + +type IConnectionPoint struct { + IUnknown +} + +type IConnectionPointVtbl struct { + IUnknownVtbl + GetConnectionInterface uintptr + GetConnectionPointContainer uintptr + Advise uintptr + Unadvise uintptr + EnumConnections uintptr +} + +func (v *IConnectionPoint) VTable() *IConnectionPointVtbl { + return (*IConnectionPointVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpoint_func.go b/vendor/github.com/go-ole/go-ole/iconnectionpoint_func.go new file mode 100644 index 0000000000..5414dc3cd3 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpoint_func.go @@ -0,0 +1,21 @@ +// +build !windows + +package ole + +import "unsafe" + +func (v *IConnectionPoint) GetConnectionInterface(piid **GUID) int32 { + return int32(0) +} + +func (v *IConnectionPoint) Advise(unknown *IUnknown) (uint32, error) { + return uint32(0), NewError(E_NOTIMPL) +} + +func (v *IConnectionPoint) Unadvise(cookie uint32) error { + return NewError(E_NOTIMPL) +} + +func (v *IConnectionPoint) EnumConnections(p *unsafe.Pointer) (err error) { + return NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpoint_windows.go b/vendor/github.com/go-ole/go-ole/iconnectionpoint_windows.go new file mode 100644 index 0000000000..32bc183248 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpoint_windows.go @@ -0,0 +1,43 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func (v *IConnectionPoint) GetConnectionInterface(piid **GUID) int32 { + // XXX: This doesn't look like it does what it's supposed to + return release((*IUnknown)(unsafe.Pointer(v))) +} + +func (v *IConnectionPoint) Advise(unknown *IUnknown) (cookie uint32, err error) { + hr, _, _ := syscall.Syscall( + v.VTable().Advise, + 3, + uintptr(unsafe.Pointer(v)), + uintptr(unsafe.Pointer(unknown)), + uintptr(unsafe.Pointer(&cookie))) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (v *IConnectionPoint) Unadvise(cookie uint32) (err error) { + hr, _, _ := syscall.Syscall( + v.VTable().Unadvise, + 2, + uintptr(unsafe.Pointer(v)), + uintptr(cookie), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (v *IConnectionPoint) EnumConnections(p *unsafe.Pointer) error { + return NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer.go b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer.go new file mode 100644 index 0000000000..165860d199 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer.go @@ -0,0 +1,17 @@ +package ole + +import "unsafe" + +type IConnectionPointContainer struct { + IUnknown +} + +type IConnectionPointContainerVtbl struct { + IUnknownVtbl + EnumConnectionPoints uintptr + FindConnectionPoint uintptr +} + +func (v *IConnectionPointContainer) VTable() *IConnectionPointContainerVtbl { + return (*IConnectionPointContainerVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_func.go b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_func.go new file mode 100644 index 0000000000..5dfa42aaeb --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_func.go @@ -0,0 +1,11 @@ +// +build !windows + +package ole + +func (v *IConnectionPointContainer) EnumConnectionPoints(points interface{}) error { + return NewError(E_NOTIMPL) +} + +func (v *IConnectionPointContainer) FindConnectionPoint(iid *GUID, point **IConnectionPoint) error { + return NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_windows.go b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_windows.go new file mode 100644 index 0000000000..ad30d79efc --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iconnectionpointcontainer_windows.go @@ -0,0 +1,25 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func (v *IConnectionPointContainer) EnumConnectionPoints(points interface{}) error { + return NewError(E_NOTIMPL) +} + +func (v *IConnectionPointContainer) FindConnectionPoint(iid *GUID, point **IConnectionPoint) (err error) { + hr, _, _ := syscall.Syscall( + v.VTable().FindConnectionPoint, + 3, + uintptr(unsafe.Pointer(v)), + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(point))) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/idispatch.go b/vendor/github.com/go-ole/go-ole/idispatch.go new file mode 100644 index 0000000000..d4af124092 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/idispatch.go @@ -0,0 +1,94 @@ +package ole + +import "unsafe" + +type IDispatch struct { + IUnknown +} + +type IDispatchVtbl struct { + IUnknownVtbl + GetTypeInfoCount uintptr + GetTypeInfo uintptr + GetIDsOfNames uintptr + Invoke uintptr +} + +func (v *IDispatch) VTable() *IDispatchVtbl { + return (*IDispatchVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IDispatch) GetIDsOfName(names []string) (dispid []int32, err error) { + dispid, err = getIDsOfName(v, names) + return +} + +func (v *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) (result *VARIANT, err error) { + result, err = invoke(v, dispid, dispatch, params...) + return +} + +func (v *IDispatch) GetTypeInfoCount() (c uint32, err error) { + c, err = getTypeInfoCount(v) + return +} + +func (v *IDispatch) GetTypeInfo() (tinfo *ITypeInfo, err error) { + tinfo, err = getTypeInfo(v) + return +} + +// GetSingleIDOfName is a helper that returns single display ID for IDispatch name. +// +// This replaces the common pattern of attempting to get a single name from the list of available +// IDs. It gives the first ID, if it is available. +func (v *IDispatch) GetSingleIDOfName(name string) (displayID int32, err error) { + var displayIDs []int32 + displayIDs, err = v.GetIDsOfName([]string{name}) + if err != nil { + return + } + displayID = displayIDs[0] + return +} + +// InvokeWithOptionalArgs accepts arguments as an array, works like Invoke. +// +// Accepts name and will attempt to retrieve Display ID to pass to Invoke. +// +// Passing params as an array is a workaround that could be fixed in later versions of Go that +// prevent passing empty params. During testing it was discovered that this is an acceptable way of +// getting around not being able to pass params normally. +func (v *IDispatch) InvokeWithOptionalArgs(name string, dispatch int16, params []interface{}) (result *VARIANT, err error) { + displayID, err := v.GetSingleIDOfName(name) + if err != nil { + return + } + + if len(params) < 1 { + result, err = v.Invoke(displayID, dispatch) + } else { + result, err = v.Invoke(displayID, dispatch, params...) + } + + return +} + +// CallMethod invokes named function with arguments on object. +func (v *IDispatch) CallMethod(name string, params ...interface{}) (*VARIANT, error) { + return v.InvokeWithOptionalArgs(name, DISPATCH_METHOD, params) +} + +// GetProperty retrieves the property with the name with the ability to pass arguments. +// +// Most of the time you will not need to pass arguments as most objects do not allow for this +// feature. Or at least, should not allow for this feature. Some servers don't follow best practices +// and this is provided for those edge cases. +func (v *IDispatch) GetProperty(name string, params ...interface{}) (*VARIANT, error) { + return v.InvokeWithOptionalArgs(name, DISPATCH_PROPERTYGET, params) +} + +// PutProperty attempts to mutate a property in the object. +func (v *IDispatch) PutProperty(name string, params ...interface{}) (*VARIANT, error) { + return v.InvokeWithOptionalArgs(name, DISPATCH_PROPERTYPUT, params) +} diff --git a/vendor/github.com/go-ole/go-ole/idispatch_func.go b/vendor/github.com/go-ole/go-ole/idispatch_func.go new file mode 100644 index 0000000000..b8fbbe319f --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/idispatch_func.go @@ -0,0 +1,19 @@ +// +build !windows + +package ole + +func getIDsOfName(disp *IDispatch, names []string) ([]int32, error) { + return []int32{}, NewError(E_NOTIMPL) +} + +func getTypeInfoCount(disp *IDispatch) (uint32, error) { + return uint32(0), NewError(E_NOTIMPL) +} + +func getTypeInfo(disp *IDispatch) (*ITypeInfo, error) { + return nil, NewError(E_NOTIMPL) +} + +func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (*VARIANT, error) { + return nil, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/idispatch_windows.go b/vendor/github.com/go-ole/go-ole/idispatch_windows.go new file mode 100644 index 0000000000..b399f04791 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/idispatch_windows.go @@ -0,0 +1,202 @@ +// +build windows + +package ole + +import ( + "math/big" + "syscall" + "time" + "unsafe" +) + +func getIDsOfName(disp *IDispatch, names []string) (dispid []int32, err error) { + wnames := make([]*uint16, len(names)) + for i := 0; i < len(names); i++ { + wnames[i] = syscall.StringToUTF16Ptr(names[i]) + } + dispid = make([]int32, len(names)) + namelen := uint32(len(names)) + hr, _, _ := syscall.Syscall6( + disp.VTable().GetIDsOfNames, + 6, + uintptr(unsafe.Pointer(disp)), + uintptr(unsafe.Pointer(IID_NULL)), + uintptr(unsafe.Pointer(&wnames[0])), + uintptr(namelen), + uintptr(GetUserDefaultLCID()), + uintptr(unsafe.Pointer(&dispid[0]))) + if hr != 0 { + err = NewError(hr) + } + return +} + +func getTypeInfoCount(disp *IDispatch) (c uint32, err error) { + hr, _, _ := syscall.Syscall( + disp.VTable().GetTypeInfoCount, + 2, + uintptr(unsafe.Pointer(disp)), + uintptr(unsafe.Pointer(&c)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func getTypeInfo(disp *IDispatch) (tinfo *ITypeInfo, err error) { + hr, _, _ := syscall.Syscall( + disp.VTable().GetTypeInfo, + 3, + uintptr(unsafe.Pointer(disp)), + uintptr(GetUserDefaultLCID()), + uintptr(unsafe.Pointer(&tinfo))) + if hr != 0 { + err = NewError(hr) + } + return +} + +func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT, err error) { + var dispparams DISPPARAMS + + if dispatch&DISPATCH_PROPERTYPUT != 0 { + dispnames := [1]int32{DISPID_PROPERTYPUT} + dispparams.rgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0])) + dispparams.cNamedArgs = 1 + } else if dispatch&DISPATCH_PROPERTYPUTREF != 0 { + dispnames := [1]int32{DISPID_PROPERTYPUT} + dispparams.rgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0])) + dispparams.cNamedArgs = 1 + } + var vargs []VARIANT + if len(params) > 0 { + vargs = make([]VARIANT, len(params)) + for i, v := range params { + //n := len(params)-i-1 + n := len(params) - i - 1 + VariantInit(&vargs[n]) + switch vv := v.(type) { + case bool: + if vv { + vargs[n] = NewVariant(VT_BOOL, 0xffff) + } else { + vargs[n] = NewVariant(VT_BOOL, 0) + } + case *bool: + vargs[n] = NewVariant(VT_BOOL|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*bool))))) + case uint8: + vargs[n] = NewVariant(VT_I1, int64(v.(uint8))) + case *uint8: + vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8))))) + case int8: + vargs[n] = NewVariant(VT_I1, int64(v.(int8))) + case *int8: + vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8))))) + case int16: + vargs[n] = NewVariant(VT_I2, int64(v.(int16))) + case *int16: + vargs[n] = NewVariant(VT_I2|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int16))))) + case uint16: + vargs[n] = NewVariant(VT_UI2, int64(v.(uint16))) + case *uint16: + vargs[n] = NewVariant(VT_UI2|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint16))))) + case int32: + vargs[n] = NewVariant(VT_I4, int64(v.(int32))) + case *int32: + vargs[n] = NewVariant(VT_I4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int32))))) + case uint32: + vargs[n] = NewVariant(VT_UI4, int64(v.(uint32))) + case *uint32: + vargs[n] = NewVariant(VT_UI4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint32))))) + case int64: + vargs[n] = NewVariant(VT_I8, int64(v.(int64))) + case *int64: + vargs[n] = NewVariant(VT_I8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int64))))) + case uint64: + vargs[n] = NewVariant(VT_UI8, int64(uintptr(v.(uint64)))) + case *uint64: + vargs[n] = NewVariant(VT_UI8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint64))))) + case int: + vargs[n] = NewVariant(VT_I4, int64(v.(int))) + case *int: + vargs[n] = NewVariant(VT_I4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int))))) + case uint: + vargs[n] = NewVariant(VT_UI4, int64(v.(uint))) + case *uint: + vargs[n] = NewVariant(VT_UI4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint))))) + case float32: + vargs[n] = NewVariant(VT_R4, *(*int64)(unsafe.Pointer(&vv))) + case *float32: + vargs[n] = NewVariant(VT_R4|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float32))))) + case float64: + vargs[n] = NewVariant(VT_R8, *(*int64)(unsafe.Pointer(&vv))) + case *float64: + vargs[n] = NewVariant(VT_R8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float64))))) + case *big.Int: + vargs[n] = NewVariant(VT_DECIMAL, v.(*big.Int).Int64()) + case string: + vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(v.(string)))))) + case *string: + vargs[n] = NewVariant(VT_BSTR|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*string))))) + case time.Time: + s := vv.Format("2006-01-02 15:04:05") + vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(s))))) + case *time.Time: + s := vv.Format("2006-01-02 15:04:05") + vargs[n] = NewVariant(VT_BSTR|VT_BYREF, int64(uintptr(unsafe.Pointer(&s)))) + case *IDispatch: + vargs[n] = NewVariant(VT_DISPATCH, int64(uintptr(unsafe.Pointer(v.(*IDispatch))))) + case **IDispatch: + vargs[n] = NewVariant(VT_DISPATCH|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(**IDispatch))))) + case nil: + vargs[n] = NewVariant(VT_NULL, 0) + case *VARIANT: + vargs[n] = NewVariant(VT_VARIANT|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*VARIANT))))) + case []byte: + safeByteArray := safeArrayFromByteSlice(v.([]byte)) + vargs[n] = NewVariant(VT_ARRAY|VT_UI1, int64(uintptr(unsafe.Pointer(safeByteArray)))) + defer VariantClear(&vargs[n]) + case []string: + safeByteArray := safeArrayFromStringSlice(v.([]string)) + vargs[n] = NewVariant(VT_ARRAY|VT_BSTR, int64(uintptr(unsafe.Pointer(safeByteArray)))) + defer VariantClear(&vargs[n]) + default: + panic("unknown type") + } + } + dispparams.rgvarg = uintptr(unsafe.Pointer(&vargs[0])) + dispparams.cArgs = uint32(len(params)) + } + + result = new(VARIANT) + var excepInfo EXCEPINFO + VariantInit(result) + hr, _, _ := syscall.Syscall9( + disp.VTable().Invoke, + 9, + uintptr(unsafe.Pointer(disp)), + uintptr(dispid), + uintptr(unsafe.Pointer(IID_NULL)), + uintptr(GetUserDefaultLCID()), + uintptr(dispatch), + uintptr(unsafe.Pointer(&dispparams)), + uintptr(unsafe.Pointer(result)), + uintptr(unsafe.Pointer(&excepInfo)), + 0) + if hr != 0 { + excepInfo.renderStrings() + excepInfo.Clear() + err = NewErrorWithSubError(hr, excepInfo.description, excepInfo) + } + for i, varg := range vargs { + n := len(params) - i - 1 + if varg.VT == VT_BSTR && varg.Val != 0 { + SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val))))) + } + if varg.VT == (VT_BSTR|VT_BYREF) && varg.Val != 0 { + *(params[n].(*string)) = LpOleStrToString(*(**uint16)(unsafe.Pointer(uintptr(varg.Val)))) + } + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/ienumvariant.go b/vendor/github.com/go-ole/go-ole/ienumvariant.go new file mode 100644 index 0000000000..2433897544 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ienumvariant.go @@ -0,0 +1,19 @@ +package ole + +import "unsafe" + +type IEnumVARIANT struct { + IUnknown +} + +type IEnumVARIANTVtbl struct { + IUnknownVtbl + Next uintptr + Skip uintptr + Reset uintptr + Clone uintptr +} + +func (v *IEnumVARIANT) VTable() *IEnumVARIANTVtbl { + return (*IEnumVARIANTVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/ienumvariant_func.go b/vendor/github.com/go-ole/go-ole/ienumvariant_func.go new file mode 100644 index 0000000000..c14848199c --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ienumvariant_func.go @@ -0,0 +1,19 @@ +// +build !windows + +package ole + +func (enum *IEnumVARIANT) Clone() (*IEnumVARIANT, error) { + return nil, NewError(E_NOTIMPL) +} + +func (enum *IEnumVARIANT) Reset() error { + return NewError(E_NOTIMPL) +} + +func (enum *IEnumVARIANT) Skip(celt uint) error { + return NewError(E_NOTIMPL) +} + +func (enum *IEnumVARIANT) Next(celt uint) (VARIANT, uint, error) { + return NewVariant(VT_NULL, int64(0)), 0, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/ienumvariant_windows.go b/vendor/github.com/go-ole/go-ole/ienumvariant_windows.go new file mode 100644 index 0000000000..4781f3b8b0 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ienumvariant_windows.go @@ -0,0 +1,63 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func (enum *IEnumVARIANT) Clone() (cloned *IEnumVARIANT, err error) { + hr, _, _ := syscall.Syscall( + enum.VTable().Clone, + 2, + uintptr(unsafe.Pointer(enum)), + uintptr(unsafe.Pointer(&cloned)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (enum *IEnumVARIANT) Reset() (err error) { + hr, _, _ := syscall.Syscall( + enum.VTable().Reset, + 1, + uintptr(unsafe.Pointer(enum)), + 0, + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (enum *IEnumVARIANT) Skip(celt uint) (err error) { + hr, _, _ := syscall.Syscall( + enum.VTable().Skip, + 2, + uintptr(unsafe.Pointer(enum)), + uintptr(celt), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} + +func (enum *IEnumVARIANT) Next(celt uint) (array VARIANT, length uint, err error) { + hr, _, _ := syscall.Syscall6( + enum.VTable().Next, + 4, + uintptr(unsafe.Pointer(enum)), + uintptr(celt), + uintptr(unsafe.Pointer(&array)), + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/iinspectable.go b/vendor/github.com/go-ole/go-ole/iinspectable.go new file mode 100644 index 0000000000..f4a19e253a --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iinspectable.go @@ -0,0 +1,18 @@ +package ole + +import "unsafe" + +type IInspectable struct { + IUnknown +} + +type IInspectableVtbl struct { + IUnknownVtbl + GetIIds uintptr + GetRuntimeClassName uintptr + GetTrustLevel uintptr +} + +func (v *IInspectable) VTable() *IInspectableVtbl { + return (*IInspectableVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/iinspectable_func.go b/vendor/github.com/go-ole/go-ole/iinspectable_func.go new file mode 100644 index 0000000000..348829bf06 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iinspectable_func.go @@ -0,0 +1,15 @@ +// +build !windows + +package ole + +func (v *IInspectable) GetIids() ([]*GUID, error) { + return []*GUID{}, NewError(E_NOTIMPL) +} + +func (v *IInspectable) GetRuntimeClassName() (string, error) { + return "", NewError(E_NOTIMPL) +} + +func (v *IInspectable) GetTrustLevel() (uint32, error) { + return uint32(0), NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/iinspectable_windows.go b/vendor/github.com/go-ole/go-ole/iinspectable_windows.go new file mode 100644 index 0000000000..4519a4aa44 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iinspectable_windows.go @@ -0,0 +1,72 @@ +// +build windows + +package ole + +import ( + "bytes" + "encoding/binary" + "reflect" + "syscall" + "unsafe" +) + +func (v *IInspectable) GetIids() (iids []*GUID, err error) { + var count uint32 + var array uintptr + hr, _, _ := syscall.Syscall( + v.VTable().GetIIds, + 3, + uintptr(unsafe.Pointer(v)), + uintptr(unsafe.Pointer(&count)), + uintptr(unsafe.Pointer(&array))) + if hr != 0 { + err = NewError(hr) + return + } + defer CoTaskMemFree(array) + + iids = make([]*GUID, count) + byteCount := count * uint32(unsafe.Sizeof(GUID{})) + slicehdr := reflect.SliceHeader{Data: array, Len: int(byteCount), Cap: int(byteCount)} + byteSlice := *(*[]byte)(unsafe.Pointer(&slicehdr)) + reader := bytes.NewReader(byteSlice) + for i := range iids { + guid := GUID{} + err = binary.Read(reader, binary.LittleEndian, &guid) + if err != nil { + return + } + iids[i] = &guid + } + return +} + +func (v *IInspectable) GetRuntimeClassName() (s string, err error) { + var hstring HString + hr, _, _ := syscall.Syscall( + v.VTable().GetRuntimeClassName, + 2, + uintptr(unsafe.Pointer(v)), + uintptr(unsafe.Pointer(&hstring)), + 0) + if hr != 0 { + err = NewError(hr) + return + } + s = hstring.String() + DeleteHString(hstring) + return +} + +func (v *IInspectable) GetTrustLevel() (level uint32, err error) { + hr, _, _ := syscall.Syscall( + v.VTable().GetTrustLevel, + 2, + uintptr(unsafe.Pointer(v)), + uintptr(unsafe.Pointer(&level)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/iprovideclassinfo.go b/vendor/github.com/go-ole/go-ole/iprovideclassinfo.go new file mode 100644 index 0000000000..25f3a6f24a --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iprovideclassinfo.go @@ -0,0 +1,21 @@ +package ole + +import "unsafe" + +type IProvideClassInfo struct { + IUnknown +} + +type IProvideClassInfoVtbl struct { + IUnknownVtbl + GetClassInfo uintptr +} + +func (v *IProvideClassInfo) VTable() *IProvideClassInfoVtbl { + return (*IProvideClassInfoVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IProvideClassInfo) GetClassInfo() (cinfo *ITypeInfo, err error) { + cinfo, err = getClassInfo(v) + return +} diff --git a/vendor/github.com/go-ole/go-ole/iprovideclassinfo_func.go b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_func.go new file mode 100644 index 0000000000..7e3cb63ea7 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_func.go @@ -0,0 +1,7 @@ +// +build !windows + +package ole + +func getClassInfo(disp *IProvideClassInfo) (tinfo *ITypeInfo, err error) { + return nil, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/iprovideclassinfo_windows.go b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_windows.go new file mode 100644 index 0000000000..2ad0163949 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iprovideclassinfo_windows.go @@ -0,0 +1,21 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func getClassInfo(disp *IProvideClassInfo) (tinfo *ITypeInfo, err error) { + hr, _, _ := syscall.Syscall( + disp.VTable().GetClassInfo, + 2, + uintptr(unsafe.Pointer(disp)), + uintptr(unsafe.Pointer(&tinfo)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/itypeinfo.go b/vendor/github.com/go-ole/go-ole/itypeinfo.go new file mode 100644 index 0000000000..dd3c5e21bb --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/itypeinfo.go @@ -0,0 +1,34 @@ +package ole + +import "unsafe" + +type ITypeInfo struct { + IUnknown +} + +type ITypeInfoVtbl struct { + IUnknownVtbl + GetTypeAttr uintptr + GetTypeComp uintptr + GetFuncDesc uintptr + GetVarDesc uintptr + GetNames uintptr + GetRefTypeOfImplType uintptr + GetImplTypeFlags uintptr + GetIDsOfNames uintptr + Invoke uintptr + GetDocumentation uintptr + GetDllEntry uintptr + GetRefTypeInfo uintptr + AddressOfMember uintptr + CreateInstance uintptr + GetMops uintptr + GetContainingTypeLib uintptr + ReleaseTypeAttr uintptr + ReleaseFuncDesc uintptr + ReleaseVarDesc uintptr +} + +func (v *ITypeInfo) VTable() *ITypeInfoVtbl { + return (*ITypeInfoVtbl)(unsafe.Pointer(v.RawVTable)) +} diff --git a/vendor/github.com/go-ole/go-ole/itypeinfo_func.go b/vendor/github.com/go-ole/go-ole/itypeinfo_func.go new file mode 100644 index 0000000000..8364a659ba --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/itypeinfo_func.go @@ -0,0 +1,7 @@ +// +build !windows + +package ole + +func (v *ITypeInfo) GetTypeAttr() (*TYPEATTR, error) { + return nil, NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/itypeinfo_windows.go b/vendor/github.com/go-ole/go-ole/itypeinfo_windows.go new file mode 100644 index 0000000000..54782b3da5 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/itypeinfo_windows.go @@ -0,0 +1,21 @@ +// +build windows + +package ole + +import ( + "syscall" + "unsafe" +) + +func (v *ITypeInfo) GetTypeAttr() (tattr *TYPEATTR, err error) { + hr, _, _ := syscall.Syscall( + uintptr(v.VTable().GetTypeAttr), + 2, + uintptr(unsafe.Pointer(v)), + uintptr(unsafe.Pointer(&tattr)), + 0) + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/iunknown.go b/vendor/github.com/go-ole/go-ole/iunknown.go new file mode 100644 index 0000000000..108f28ea61 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iunknown.go @@ -0,0 +1,57 @@ +package ole + +import "unsafe" + +type IUnknown struct { + RawVTable *interface{} +} + +type IUnknownVtbl struct { + QueryInterface uintptr + AddRef uintptr + Release uintptr +} + +type UnknownLike interface { + QueryInterface(iid *GUID) (disp *IDispatch, err error) + AddRef() int32 + Release() int32 +} + +func (v *IUnknown) VTable() *IUnknownVtbl { + return (*IUnknownVtbl)(unsafe.Pointer(v.RawVTable)) +} + +func (v *IUnknown) PutQueryInterface(interfaceID *GUID, obj interface{}) error { + return reflectQueryInterface(v, v.VTable().QueryInterface, interfaceID, obj) +} + +func (v *IUnknown) IDispatch(interfaceID *GUID) (dispatch *IDispatch, err error) { + err = v.PutQueryInterface(interfaceID, &dispatch) + return +} + +func (v *IUnknown) IEnumVARIANT(interfaceID *GUID) (enum *IEnumVARIANT, err error) { + err = v.PutQueryInterface(interfaceID, &enum) + return +} + +func (v *IUnknown) QueryInterface(iid *GUID) (*IDispatch, error) { + return queryInterface(v, iid) +} + +func (v *IUnknown) MustQueryInterface(iid *GUID) (disp *IDispatch) { + unk, err := queryInterface(v, iid) + if err != nil { + panic(err) + } + return unk +} + +func (v *IUnknown) AddRef() int32 { + return addRef(v) +} + +func (v *IUnknown) Release() int32 { + return release(v) +} diff --git a/vendor/github.com/go-ole/go-ole/iunknown_func.go b/vendor/github.com/go-ole/go-ole/iunknown_func.go new file mode 100644 index 0000000000..d0a62cfd73 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iunknown_func.go @@ -0,0 +1,19 @@ +// +build !windows + +package ole + +func reflectQueryInterface(self interface{}, method uintptr, interfaceID *GUID, obj interface{}) (err error) { + return NewError(E_NOTIMPL) +} + +func queryInterface(unk *IUnknown, iid *GUID) (disp *IDispatch, err error) { + return nil, NewError(E_NOTIMPL) +} + +func addRef(unk *IUnknown) int32 { + return 0 +} + +func release(unk *IUnknown) int32 { + return 0 +} diff --git a/vendor/github.com/go-ole/go-ole/iunknown_windows.go b/vendor/github.com/go-ole/go-ole/iunknown_windows.go new file mode 100644 index 0000000000..ede5bb8c17 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/iunknown_windows.go @@ -0,0 +1,58 @@ +// +build windows + +package ole + +import ( + "reflect" + "syscall" + "unsafe" +) + +func reflectQueryInterface(self interface{}, method uintptr, interfaceID *GUID, obj interface{}) (err error) { + selfValue := reflect.ValueOf(self).Elem() + objValue := reflect.ValueOf(obj).Elem() + + hr, _, _ := syscall.Syscall( + method, + 3, + selfValue.UnsafeAddr(), + uintptr(unsafe.Pointer(interfaceID)), + objValue.Addr().Pointer()) + if hr != 0 { + err = NewError(hr) + } + return +} + +func queryInterface(unk *IUnknown, iid *GUID) (disp *IDispatch, err error) { + hr, _, _ := syscall.Syscall( + unk.VTable().QueryInterface, + 3, + uintptr(unsafe.Pointer(unk)), + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(&disp))) + if hr != 0 { + err = NewError(hr) + } + return +} + +func addRef(unk *IUnknown) int32 { + ret, _, _ := syscall.Syscall( + unk.VTable().AddRef, + 1, + uintptr(unsafe.Pointer(unk)), + 0, + 0) + return int32(ret) +} + +func release(unk *IUnknown) int32 { + ret, _, _ := syscall.Syscall( + unk.VTable().Release, + 1, + uintptr(unsafe.Pointer(unk)), + 0, + 0) + return int32(ret) +} diff --git a/vendor/github.com/go-ole/go-ole/ole.go b/vendor/github.com/go-ole/go-ole/ole.go new file mode 100644 index 0000000000..dbd132bbd7 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/ole.go @@ -0,0 +1,190 @@ +package ole + +import ( + "fmt" + "strings" + "unsafe" +) + +// DISPPARAMS are the arguments that passed to methods or property. +type DISPPARAMS struct { + rgvarg uintptr + rgdispidNamedArgs uintptr + cArgs uint32 + cNamedArgs uint32 +} + +// EXCEPINFO defines exception info. +type EXCEPINFO struct { + wCode uint16 + wReserved uint16 + bstrSource *uint16 + bstrDescription *uint16 + bstrHelpFile *uint16 + dwHelpContext uint32 + pvReserved uintptr + pfnDeferredFillIn uintptr + scode uint32 + + // Go-specific part. Don't move upper cos it'll break structure layout for native code. + rendered bool + source string + description string + helpFile string +} + +// renderStrings translates BSTR strings to Go ones so `.Error` and `.String` +// could be safely called after `.Clear`. We need this when we can't rely on +// a caller to call `.Clear`. +func (e *EXCEPINFO) renderStrings() { + e.rendered = true + if e.bstrSource == nil { + e.source = "" + } else { + e.source = BstrToString(e.bstrSource) + } + if e.bstrDescription == nil { + e.description = "" + } else { + e.description = BstrToString(e.bstrDescription) + } + if e.bstrHelpFile == nil { + e.helpFile = "" + } else { + e.helpFile = BstrToString(e.bstrHelpFile) + } +} + +// Clear frees BSTR strings inside an EXCEPINFO and set it to NULL. +func (e *EXCEPINFO) Clear() { + freeBSTR := func(s *uint16) { + // SysFreeString don't return errors and is safe for call's on NULL. + // https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-sysfreestring + _ = SysFreeString((*int16)(unsafe.Pointer(s))) + } + + if e.bstrSource != nil { + freeBSTR(e.bstrSource) + e.bstrSource = nil + } + if e.bstrDescription != nil { + freeBSTR(e.bstrDescription) + e.bstrDescription = nil + } + if e.bstrHelpFile != nil { + freeBSTR(e.bstrHelpFile) + e.bstrHelpFile = nil + } +} + +// WCode return wCode in EXCEPINFO. +func (e EXCEPINFO) WCode() uint16 { + return e.wCode +} + +// SCODE return scode in EXCEPINFO. +func (e EXCEPINFO) SCODE() uint32 { + return e.scode +} + +// String convert EXCEPINFO to string. +func (e EXCEPINFO) String() string { + if !e.rendered { + e.renderStrings() + } + return fmt.Sprintf( + "wCode: %#x, bstrSource: %v, bstrDescription: %v, bstrHelpFile: %v, dwHelpContext: %#x, scode: %#x", + e.wCode, e.source, e.description, e.helpFile, e.dwHelpContext, e.scode, + ) +} + +// Error implements error interface and returns error string. +func (e EXCEPINFO) Error() string { + if !e.rendered { + e.renderStrings() + } + + if e.description != "" { + return strings.TrimSpace(e.description) + } + + code := e.scode + if e.wCode != 0 { + code = uint32(e.wCode) + } + return fmt.Sprintf("%v: %#x", e.source, code) +} + +// PARAMDATA defines parameter data type. +type PARAMDATA struct { + Name *int16 + Vt uint16 +} + +// METHODDATA defines method info. +type METHODDATA struct { + Name *uint16 + Data *PARAMDATA + Dispid int32 + Meth uint32 + CC int32 + CArgs uint32 + Flags uint16 + VtReturn uint32 +} + +// INTERFACEDATA defines interface info. +type INTERFACEDATA struct { + MethodData *METHODDATA + CMembers uint32 +} + +// Point is 2D vector type. +type Point struct { + X int32 + Y int32 +} + +// Msg is message between processes. +type Msg struct { + Hwnd uint32 + Message uint32 + Wparam int32 + Lparam int32 + Time uint32 + Pt Point +} + +// TYPEDESC defines data type. +type TYPEDESC struct { + Hreftype uint32 + VT uint16 +} + +// IDLDESC defines IDL info. +type IDLDESC struct { + DwReserved uint32 + WIDLFlags uint16 +} + +// TYPEATTR defines type info. +type TYPEATTR struct { + Guid GUID + Lcid uint32 + dwReserved uint32 + MemidConstructor int32 + MemidDestructor int32 + LpstrSchema *uint16 + CbSizeInstance uint32 + Typekind int32 + CFuncs uint16 + CVars uint16 + CImplTypes uint16 + CbSizeVft uint16 + CbAlignment uint16 + WTypeFlags uint16 + WMajorVerNum uint16 + WMinorVerNum uint16 + TdescAlias TYPEDESC + IdldescType IDLDESC +} diff --git a/vendor/github.com/go-ole/go-ole/oleutil/connection.go b/vendor/github.com/go-ole/go-ole/oleutil/connection.go new file mode 100644 index 0000000000..60df73cda0 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/connection.go @@ -0,0 +1,100 @@ +// +build windows + +package oleutil + +import ( + "reflect" + "unsafe" + + ole "github.com/go-ole/go-ole" +) + +type stdDispatch struct { + lpVtbl *stdDispatchVtbl + ref int32 + iid *ole.GUID + iface interface{} + funcMap map[string]int32 +} + +type stdDispatchVtbl struct { + pQueryInterface uintptr + pAddRef uintptr + pRelease uintptr + pGetTypeInfoCount uintptr + pGetTypeInfo uintptr + pGetIDsOfNames uintptr + pInvoke uintptr +} + +func dispQueryInterface(this *ole.IUnknown, iid *ole.GUID, punk **ole.IUnknown) uint32 { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + *punk = nil + if ole.IsEqualGUID(iid, ole.IID_IUnknown) || + ole.IsEqualGUID(iid, ole.IID_IDispatch) { + dispAddRef(this) + *punk = this + return ole.S_OK + } + if ole.IsEqualGUID(iid, pthis.iid) { + dispAddRef(this) + *punk = this + return ole.S_OK + } + return ole.E_NOINTERFACE +} + +func dispAddRef(this *ole.IUnknown) int32 { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + pthis.ref++ + return pthis.ref +} + +func dispRelease(this *ole.IUnknown) int32 { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + pthis.ref-- + return pthis.ref +} + +func dispGetIDsOfNames(this *ole.IUnknown, iid *ole.GUID, wnames []*uint16, namelen int, lcid int, pdisp []int32) uintptr { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + names := make([]string, len(wnames)) + for i := 0; i < len(names); i++ { + names[i] = ole.LpOleStrToString(wnames[i]) + } + for n := 0; n < namelen; n++ { + if id, ok := pthis.funcMap[names[n]]; ok { + pdisp[n] = id + } + } + return ole.S_OK +} + +func dispGetTypeInfoCount(pcount *int) uintptr { + if pcount != nil { + *pcount = 0 + } + return ole.S_OK +} + +func dispGetTypeInfo(ptypeif *uintptr) uintptr { + return ole.E_NOTIMPL +} + +func dispInvoke(this *ole.IDispatch, dispid int32, riid *ole.GUID, lcid int, flags int16, dispparams *ole.DISPPARAMS, result *ole.VARIANT, pexcepinfo *ole.EXCEPINFO, nerr *uint) uintptr { + pthis := (*stdDispatch)(unsafe.Pointer(this)) + found := "" + for name, id := range pthis.funcMap { + if id == dispid { + found = name + } + } + if found != "" { + rv := reflect.ValueOf(pthis.iface).Elem() + rm := rv.MethodByName(found) + rr := rm.Call([]reflect.Value{}) + println(len(rr)) + return ole.S_OK + } + return ole.E_NOTIMPL +} diff --git a/vendor/github.com/go-ole/go-ole/oleutil/connection_func.go b/vendor/github.com/go-ole/go-ole/oleutil/connection_func.go new file mode 100644 index 0000000000..8818fb8275 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/connection_func.go @@ -0,0 +1,10 @@ +// +build !windows + +package oleutil + +import ole "github.com/go-ole/go-ole" + +// ConnectObject creates a connection point between two services for communication. +func ConnectObject(disp *ole.IDispatch, iid *ole.GUID, idisp interface{}) (uint32, error) { + return 0, ole.NewError(ole.E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/oleutil/connection_windows.go b/vendor/github.com/go-ole/go-ole/oleutil/connection_windows.go new file mode 100644 index 0000000000..ab9c0d8dcb --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/connection_windows.go @@ -0,0 +1,58 @@ +// +build windows + +package oleutil + +import ( + "reflect" + "syscall" + "unsafe" + + ole "github.com/go-ole/go-ole" +) + +// ConnectObject creates a connection point between two services for communication. +func ConnectObject(disp *ole.IDispatch, iid *ole.GUID, idisp interface{}) (cookie uint32, err error) { + unknown, err := disp.QueryInterface(ole.IID_IConnectionPointContainer) + if err != nil { + return + } + + container := (*ole.IConnectionPointContainer)(unsafe.Pointer(unknown)) + var point *ole.IConnectionPoint + err = container.FindConnectionPoint(iid, &point) + if err != nil { + return + } + if edisp, ok := idisp.(*ole.IUnknown); ok { + cookie, err = point.Advise(edisp) + container.Release() + if err != nil { + return + } + } + rv := reflect.ValueOf(disp).Elem() + if rv.Type().Kind() == reflect.Struct { + dest := &stdDispatch{} + dest.lpVtbl = &stdDispatchVtbl{} + dest.lpVtbl.pQueryInterface = syscall.NewCallback(dispQueryInterface) + dest.lpVtbl.pAddRef = syscall.NewCallback(dispAddRef) + dest.lpVtbl.pRelease = syscall.NewCallback(dispRelease) + dest.lpVtbl.pGetTypeInfoCount = syscall.NewCallback(dispGetTypeInfoCount) + dest.lpVtbl.pGetTypeInfo = syscall.NewCallback(dispGetTypeInfo) + dest.lpVtbl.pGetIDsOfNames = syscall.NewCallback(dispGetIDsOfNames) + dest.lpVtbl.pInvoke = syscall.NewCallback(dispInvoke) + dest.iface = disp + dest.iid = iid + cookie, err = point.Advise((*ole.IUnknown)(unsafe.Pointer(dest))) + container.Release() + if err != nil { + point.Release() + return + } + return + } + + container.Release() + + return 0, ole.NewError(ole.E_INVALIDARG) +} diff --git a/vendor/github.com/go-ole/go-ole/oleutil/go-get.go b/vendor/github.com/go-ole/go-ole/oleutil/go-get.go new file mode 100644 index 0000000000..58347628f2 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/go-get.go @@ -0,0 +1,6 @@ +// This file is here so go get succeeds as without it errors with: +// no buildable Go source files in ... +// +// +build !windows + +package oleutil diff --git a/vendor/github.com/go-ole/go-ole/oleutil/oleutil.go b/vendor/github.com/go-ole/go-ole/oleutil/oleutil.go new file mode 100644 index 0000000000..f7803c1e30 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/oleutil/oleutil.go @@ -0,0 +1,127 @@ +package oleutil + +import ole "github.com/go-ole/go-ole" + +// ClassIDFrom retrieves class ID whether given is program ID or application string. +func ClassIDFrom(programID string) (classID *ole.GUID, err error) { + return ole.ClassIDFrom(programID) +} + +// CreateObject creates object from programID based on interface type. +// +// Only supports IUnknown. +// +// Program ID can be either program ID or application string. +func CreateObject(programID string) (unknown *ole.IUnknown, err error) { + classID, err := ole.ClassIDFrom(programID) + if err != nil { + return + } + + unknown, err = ole.CreateInstance(classID, ole.IID_IUnknown) + if err != nil { + return + } + + return +} + +// GetActiveObject retrieves active object for program ID and interface ID based +// on interface type. +// +// Only supports IUnknown. +// +// Program ID can be either program ID or application string. +func GetActiveObject(programID string) (unknown *ole.IUnknown, err error) { + classID, err := ole.ClassIDFrom(programID) + if err != nil { + return + } + + unknown, err = ole.GetActiveObject(classID, ole.IID_IUnknown) + if err != nil { + return + } + + return +} + +// CallMethod calls method on IDispatch with parameters. +func CallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_METHOD, params) +} + +// MustCallMethod calls method on IDispatch with parameters or panics. +func MustCallMethod(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := CallMethod(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +// GetProperty retrieves property from IDispatch. +func GetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYGET, params) +} + +// MustGetProperty retrieves property from IDispatch or panics. +func MustGetProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := GetProperty(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +// PutProperty mutates property. +func PutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUT, params) +} + +// MustPutProperty mutates property or panics. +func MustPutProperty(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := PutProperty(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +// PutPropertyRef mutates property reference. +func PutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT, err error) { + return disp.InvokeWithOptionalArgs(name, ole.DISPATCH_PROPERTYPUTREF, params) +} + +// MustPutPropertyRef mutates property reference or panics. +func MustPutPropertyRef(disp *ole.IDispatch, name string, params ...interface{}) (result *ole.VARIANT) { + r, err := PutPropertyRef(disp, name, params...) + if err != nil { + panic(err.Error()) + } + return r +} + +func ForEach(disp *ole.IDispatch, f func(v *ole.VARIANT) error) error { + newEnum, err := disp.GetProperty("_NewEnum") + if err != nil { + return err + } + defer newEnum.Clear() + + enum, err := newEnum.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant) + if err != nil { + return err + } + defer enum.Release() + + for item, length, err := enum.Next(1); length > 0; item, length, err = enum.Next(1) { + if err != nil { + return err + } + if ferr := f(&item); ferr != nil { + return ferr + } + } + return nil +} diff --git a/vendor/github.com/go-ole/go-ole/safearray.go b/vendor/github.com/go-ole/go-ole/safearray.go new file mode 100644 index 0000000000..a5201b56c3 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearray.go @@ -0,0 +1,27 @@ +// Package is meant to retrieve and process safe array data returned from COM. + +package ole + +// SafeArrayBound defines the SafeArray boundaries. +type SafeArrayBound struct { + Elements uint32 + LowerBound int32 +} + +// SafeArray is how COM handles arrays. +type SafeArray struct { + Dimensions uint16 + FeaturesFlag uint16 + ElementsSize uint32 + LocksAmount uint32 + Data uint32 + Bounds [16]byte +} + +// SAFEARRAY is obsolete, exists for backwards compatibility. +// Use SafeArray +type SAFEARRAY SafeArray + +// SAFEARRAYBOUND is obsolete, exists for backwards compatibility. +// Use SafeArrayBound +type SAFEARRAYBOUND SafeArrayBound diff --git a/vendor/github.com/go-ole/go-ole/safearray_func.go b/vendor/github.com/go-ole/go-ole/safearray_func.go new file mode 100644 index 0000000000..0dee670ceb --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearray_func.go @@ -0,0 +1,211 @@ +// +build !windows + +package ole + +import ( + "unsafe" +) + +// safeArrayAccessData returns raw array pointer. +// +// AKA: SafeArrayAccessData in Windows API. +func safeArrayAccessData(safearray *SafeArray) (uintptr, error) { + return uintptr(0), NewError(E_NOTIMPL) +} + +// safeArrayUnaccessData releases raw array. +// +// AKA: SafeArrayUnaccessData in Windows API. +func safeArrayUnaccessData(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayAllocData allocates SafeArray. +// +// AKA: SafeArrayAllocData in Windows API. +func safeArrayAllocData(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayAllocDescriptor allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptor in Windows API. +func safeArrayAllocDescriptor(dimensions uint32) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayAllocDescriptorEx allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptorEx in Windows API. +func safeArrayAllocDescriptorEx(variantType VT, dimensions uint32) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCopy returns copy of SafeArray. +// +// AKA: SafeArrayCopy in Windows API. +func safeArrayCopy(original *SafeArray) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCopyData duplicates SafeArray into another SafeArray object. +// +// AKA: SafeArrayCopyData in Windows API. +func safeArrayCopyData(original *SafeArray, duplicate *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayCreate creates SafeArray. +// +// AKA: SafeArrayCreate in Windows API. +func safeArrayCreate(variantType VT, dimensions uint32, bounds *SafeArrayBound) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCreateEx creates SafeArray. +// +// AKA: SafeArrayCreateEx in Windows API. +func safeArrayCreateEx(variantType VT, dimensions uint32, bounds *SafeArrayBound, extra uintptr) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCreateVector creates SafeArray. +// +// AKA: SafeArrayCreateVector in Windows API. +func safeArrayCreateVector(variantType VT, lowerBound int32, length uint32) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayCreateVectorEx creates SafeArray. +// +// AKA: SafeArrayCreateVectorEx in Windows API. +func safeArrayCreateVectorEx(variantType VT, lowerBound int32, length uint32, extra uintptr) (*SafeArray, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayDestroy destroys SafeArray object. +// +// AKA: SafeArrayDestroy in Windows API. +func safeArrayDestroy(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayDestroyData destroys SafeArray object. +// +// AKA: SafeArrayDestroyData in Windows API. +func safeArrayDestroyData(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayDestroyDescriptor destroys SafeArray object. +// +// AKA: SafeArrayDestroyDescriptor in Windows API. +func safeArrayDestroyDescriptor(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayGetDim is the amount of dimensions in the SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetDim in Windows API. +func safeArrayGetDim(safearray *SafeArray) (*uint32, error) { + u := uint32(0) + return &u, NewError(E_NOTIMPL) +} + +// safeArrayGetElementSize is the element size in bytes. +// +// AKA: SafeArrayGetElemsize in Windows API. +func safeArrayGetElementSize(safearray *SafeArray) (*uint32, error) { + u := uint32(0) + return &u, NewError(E_NOTIMPL) +} + +// safeArrayGetElement retrieves element at given index. +func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error { + return NewError(E_NOTIMPL) +} + +// safeArrayGetElement retrieves element at given index and converts to string. +func safeArrayGetElementString(safearray *SafeArray, index int32) (string, error) { + return "", NewError(E_NOTIMPL) +} + +// safeArrayGetIID is the InterfaceID of the elements in the SafeArray. +// +// AKA: SafeArrayGetIID in Windows API. +func safeArrayGetIID(safearray *SafeArray) (*GUID, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArrayGetLBound returns lower bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetLBound in Windows API. +func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int32, error) { + return int32(0), NewError(E_NOTIMPL) +} + +// safeArrayGetUBound returns upper bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetUBound in Windows API. +func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int32, error) { + return int32(0), NewError(E_NOTIMPL) +} + +// safeArrayGetVartype returns data type of SafeArray. +// +// AKA: SafeArrayGetVartype in Windows API. +func safeArrayGetVartype(safearray *SafeArray) (uint16, error) { + return uint16(0), NewError(E_NOTIMPL) +} + +// safeArrayLock locks SafeArray for reading to modify SafeArray. +// +// This must be called during some calls to ensure that another process does not +// read or write to the SafeArray during editing. +// +// AKA: SafeArrayLock in Windows API. +func safeArrayLock(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayUnlock unlocks SafeArray for reading. +// +// AKA: SafeArrayUnlock in Windows API. +func safeArrayUnlock(safearray *SafeArray) error { + return NewError(E_NOTIMPL) +} + +// safeArrayPutElement stores the data element at the specified location in the +// array. +// +// AKA: SafeArrayPutElement in Windows API. +func safeArrayPutElement(safearray *SafeArray, index int64, element uintptr) error { + return NewError(E_NOTIMPL) +} + +// safeArrayGetRecordInfo accesses IRecordInfo info for custom types. +// +// AKA: SafeArrayGetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. +func safeArrayGetRecordInfo(safearray *SafeArray) (interface{}, error) { + return nil, NewError(E_NOTIMPL) +} + +// safeArraySetRecordInfo mutates IRecordInfo info for custom types. +// +// AKA: SafeArraySetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. +func safeArraySetRecordInfo(safearray *SafeArray, recordInfo interface{}) error { + return NewError(E_NOTIMPL) +} diff --git a/vendor/github.com/go-ole/go-ole/safearray_windows.go b/vendor/github.com/go-ole/go-ole/safearray_windows.go new file mode 100644 index 0000000000..0c1b3a10ff --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearray_windows.go @@ -0,0 +1,337 @@ +// +build windows + +package ole + +import ( + "unsafe" +) + +var ( + procSafeArrayAccessData = modoleaut32.NewProc("SafeArrayAccessData") + procSafeArrayAllocData = modoleaut32.NewProc("SafeArrayAllocData") + procSafeArrayAllocDescriptor = modoleaut32.NewProc("SafeArrayAllocDescriptor") + procSafeArrayAllocDescriptorEx = modoleaut32.NewProc("SafeArrayAllocDescriptorEx") + procSafeArrayCopy = modoleaut32.NewProc("SafeArrayCopy") + procSafeArrayCopyData = modoleaut32.NewProc("SafeArrayCopyData") + procSafeArrayCreate = modoleaut32.NewProc("SafeArrayCreate") + procSafeArrayCreateEx = modoleaut32.NewProc("SafeArrayCreateEx") + procSafeArrayCreateVector = modoleaut32.NewProc("SafeArrayCreateVector") + procSafeArrayCreateVectorEx = modoleaut32.NewProc("SafeArrayCreateVectorEx") + procSafeArrayDestroy = modoleaut32.NewProc("SafeArrayDestroy") + procSafeArrayDestroyData = modoleaut32.NewProc("SafeArrayDestroyData") + procSafeArrayDestroyDescriptor = modoleaut32.NewProc("SafeArrayDestroyDescriptor") + procSafeArrayGetDim = modoleaut32.NewProc("SafeArrayGetDim") + procSafeArrayGetElement = modoleaut32.NewProc("SafeArrayGetElement") + procSafeArrayGetElemsize = modoleaut32.NewProc("SafeArrayGetElemsize") + procSafeArrayGetIID = modoleaut32.NewProc("SafeArrayGetIID") + procSafeArrayGetLBound = modoleaut32.NewProc("SafeArrayGetLBound") + procSafeArrayGetUBound = modoleaut32.NewProc("SafeArrayGetUBound") + procSafeArrayGetVartype = modoleaut32.NewProc("SafeArrayGetVartype") + procSafeArrayLock = modoleaut32.NewProc("SafeArrayLock") + procSafeArrayPtrOfIndex = modoleaut32.NewProc("SafeArrayPtrOfIndex") + procSafeArrayUnaccessData = modoleaut32.NewProc("SafeArrayUnaccessData") + procSafeArrayUnlock = modoleaut32.NewProc("SafeArrayUnlock") + procSafeArrayPutElement = modoleaut32.NewProc("SafeArrayPutElement") + //procSafeArrayRedim = modoleaut32.NewProc("SafeArrayRedim") // TODO + //procSafeArraySetIID = modoleaut32.NewProc("SafeArraySetIID") // TODO + procSafeArrayGetRecordInfo = modoleaut32.NewProc("SafeArrayGetRecordInfo") + procSafeArraySetRecordInfo = modoleaut32.NewProc("SafeArraySetRecordInfo") +) + +// safeArrayAccessData returns raw array pointer. +// +// AKA: SafeArrayAccessData in Windows API. +// Todo: Test +func safeArrayAccessData(safearray *SafeArray) (element uintptr, err error) { + err = convertHresultToError( + procSafeArrayAccessData.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&element)))) + return +} + +// safeArrayUnaccessData releases raw array. +// +// AKA: SafeArrayUnaccessData in Windows API. +func safeArrayUnaccessData(safearray *SafeArray) (err error) { + err = convertHresultToError(procSafeArrayUnaccessData.Call(uintptr(unsafe.Pointer(safearray)))) + return +} + +// safeArrayAllocData allocates SafeArray. +// +// AKA: SafeArrayAllocData in Windows API. +func safeArrayAllocData(safearray *SafeArray) (err error) { + err = convertHresultToError(procSafeArrayAllocData.Call(uintptr(unsafe.Pointer(safearray)))) + return +} + +// safeArrayAllocDescriptor allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptor in Windows API. +func safeArrayAllocDescriptor(dimensions uint32) (safearray *SafeArray, err error) { + err = convertHresultToError( + procSafeArrayAllocDescriptor.Call(uintptr(dimensions), uintptr(unsafe.Pointer(&safearray)))) + return +} + +// safeArrayAllocDescriptorEx allocates SafeArray. +// +// AKA: SafeArrayAllocDescriptorEx in Windows API. +func safeArrayAllocDescriptorEx(variantType VT, dimensions uint32) (safearray *SafeArray, err error) { + err = convertHresultToError( + procSafeArrayAllocDescriptorEx.Call( + uintptr(variantType), + uintptr(dimensions), + uintptr(unsafe.Pointer(&safearray)))) + return +} + +// safeArrayCopy returns copy of SafeArray. +// +// AKA: SafeArrayCopy in Windows API. +func safeArrayCopy(original *SafeArray) (safearray *SafeArray, err error) { + err = convertHresultToError( + procSafeArrayCopy.Call( + uintptr(unsafe.Pointer(original)), + uintptr(unsafe.Pointer(&safearray)))) + return +} + +// safeArrayCopyData duplicates SafeArray into another SafeArray object. +// +// AKA: SafeArrayCopyData in Windows API. +func safeArrayCopyData(original *SafeArray, duplicate *SafeArray) (err error) { + err = convertHresultToError( + procSafeArrayCopyData.Call( + uintptr(unsafe.Pointer(original)), + uintptr(unsafe.Pointer(duplicate)))) + return +} + +// safeArrayCreate creates SafeArray. +// +// AKA: SafeArrayCreate in Windows API. +func safeArrayCreate(variantType VT, dimensions uint32, bounds *SafeArrayBound) (safearray *SafeArray, err error) { + sa, _, err := procSafeArrayCreate.Call( + uintptr(variantType), + uintptr(dimensions), + uintptr(unsafe.Pointer(bounds))) + safearray = (*SafeArray)(unsafe.Pointer(&sa)) + return +} + +// safeArrayCreateEx creates SafeArray. +// +// AKA: SafeArrayCreateEx in Windows API. +func safeArrayCreateEx(variantType VT, dimensions uint32, bounds *SafeArrayBound, extra uintptr) (safearray *SafeArray, err error) { + sa, _, err := procSafeArrayCreateEx.Call( + uintptr(variantType), + uintptr(dimensions), + uintptr(unsafe.Pointer(bounds)), + extra) + safearray = (*SafeArray)(unsafe.Pointer(sa)) + return +} + +// safeArrayCreateVector creates SafeArray. +// +// AKA: SafeArrayCreateVector in Windows API. +func safeArrayCreateVector(variantType VT, lowerBound int32, length uint32) (safearray *SafeArray, err error) { + sa, _, err := procSafeArrayCreateVector.Call( + uintptr(variantType), + uintptr(lowerBound), + uintptr(length)) + safearray = (*SafeArray)(unsafe.Pointer(sa)) + return +} + +// safeArrayCreateVectorEx creates SafeArray. +// +// AKA: SafeArrayCreateVectorEx in Windows API. +func safeArrayCreateVectorEx(variantType VT, lowerBound int32, length uint32, extra uintptr) (safearray *SafeArray, err error) { + sa, _, err := procSafeArrayCreateVectorEx.Call( + uintptr(variantType), + uintptr(lowerBound), + uintptr(length), + extra) + safearray = (*SafeArray)(unsafe.Pointer(sa)) + return +} + +// safeArrayDestroy destroys SafeArray object. +// +// AKA: SafeArrayDestroy in Windows API. +func safeArrayDestroy(safearray *SafeArray) (err error) { + err = convertHresultToError(procSafeArrayDestroy.Call(uintptr(unsafe.Pointer(safearray)))) + return +} + +// safeArrayDestroyData destroys SafeArray object. +// +// AKA: SafeArrayDestroyData in Windows API. +func safeArrayDestroyData(safearray *SafeArray) (err error) { + err = convertHresultToError(procSafeArrayDestroyData.Call(uintptr(unsafe.Pointer(safearray)))) + return +} + +// safeArrayDestroyDescriptor destroys SafeArray object. +// +// AKA: SafeArrayDestroyDescriptor in Windows API. +func safeArrayDestroyDescriptor(safearray *SafeArray) (err error) { + err = convertHresultToError(procSafeArrayDestroyDescriptor.Call(uintptr(unsafe.Pointer(safearray)))) + return +} + +// safeArrayGetDim is the amount of dimensions in the SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetDim in Windows API. +func safeArrayGetDim(safearray *SafeArray) (dimensions *uint32, err error) { + l, _, err := procSafeArrayGetDim.Call(uintptr(unsafe.Pointer(safearray))) + dimensions = (*uint32)(unsafe.Pointer(l)) + return +} + +// safeArrayGetElementSize is the element size in bytes. +// +// AKA: SafeArrayGetElemsize in Windows API. +func safeArrayGetElementSize(safearray *SafeArray) (length *uint32, err error) { + l, _, err := procSafeArrayGetElemsize.Call(uintptr(unsafe.Pointer(safearray))) + length = (*uint32)(unsafe.Pointer(l)) + return +} + +// safeArrayGetElement retrieves element at given index. +func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error { + return convertHresultToError( + procSafeArrayGetElement.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&index)), + uintptr(pv))) +} + +// safeArrayGetElementString retrieves element at given index and converts to string. +func safeArrayGetElementString(safearray *SafeArray, index int32) (str string, err error) { + var element *int16 + err = convertHresultToError( + procSafeArrayGetElement.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&index)), + uintptr(unsafe.Pointer(&element)))) + str = BstrToString(*(**uint16)(unsafe.Pointer(&element))) + SysFreeString(element) + return +} + +// safeArrayGetIID is the InterfaceID of the elements in the SafeArray. +// +// AKA: SafeArrayGetIID in Windows API. +func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) { + err = convertHresultToError( + procSafeArrayGetIID.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&guid)))) + return +} + +// safeArrayGetLBound returns lower bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetLBound in Windows API. +func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int32, err error) { + err = convertHresultToError( + procSafeArrayGetLBound.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(dimension), + uintptr(unsafe.Pointer(&lowerBound)))) + return +} + +// safeArrayGetUBound returns upper bounds of SafeArray. +// +// SafeArrays may have multiple dimensions. Meaning, it could be +// multidimensional array. +// +// AKA: SafeArrayGetUBound in Windows API. +func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int32, err error) { + err = convertHresultToError( + procSafeArrayGetUBound.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(dimension), + uintptr(unsafe.Pointer(&upperBound)))) + return +} + +// safeArrayGetVartype returns data type of SafeArray. +// +// AKA: SafeArrayGetVartype in Windows API. +func safeArrayGetVartype(safearray *SafeArray) (varType uint16, err error) { + err = convertHresultToError( + procSafeArrayGetVartype.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&varType)))) + return +} + +// safeArrayLock locks SafeArray for reading to modify SafeArray. +// +// This must be called during some calls to ensure that another process does not +// read or write to the SafeArray during editing. +// +// AKA: SafeArrayLock in Windows API. +func safeArrayLock(safearray *SafeArray) (err error) { + err = convertHresultToError(procSafeArrayLock.Call(uintptr(unsafe.Pointer(safearray)))) + return +} + +// safeArrayUnlock unlocks SafeArray for reading. +// +// AKA: SafeArrayUnlock in Windows API. +func safeArrayUnlock(safearray *SafeArray) (err error) { + err = convertHresultToError(procSafeArrayUnlock.Call(uintptr(unsafe.Pointer(safearray)))) + return +} + +// safeArrayPutElement stores the data element at the specified location in the +// array. +// +// AKA: SafeArrayPutElement in Windows API. +func safeArrayPutElement(safearray *SafeArray, index int64, element uintptr) (err error) { + err = convertHresultToError( + procSafeArrayPutElement.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&index)), + uintptr(unsafe.Pointer(element)))) + return +} + +// safeArrayGetRecordInfo accesses IRecordInfo info for custom types. +// +// AKA: SafeArrayGetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. +func safeArrayGetRecordInfo(safearray *SafeArray) (recordInfo interface{}, err error) { + err = convertHresultToError( + procSafeArrayGetRecordInfo.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&recordInfo)))) + return +} + +// safeArraySetRecordInfo mutates IRecordInfo info for custom types. +// +// AKA: SafeArraySetRecordInfo in Windows API. +// +// XXX: Must implement IRecordInfo interface for this to return. +func safeArraySetRecordInfo(safearray *SafeArray, recordInfo interface{}) (err error) { + err = convertHresultToError( + procSafeArraySetRecordInfo.Call( + uintptr(unsafe.Pointer(safearray)), + uintptr(unsafe.Pointer(&recordInfo)))) + return +} diff --git a/vendor/github.com/go-ole/go-ole/safearrayconversion.go b/vendor/github.com/go-ole/go-ole/safearrayconversion.go new file mode 100644 index 0000000000..da737293d7 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearrayconversion.go @@ -0,0 +1,140 @@ +// Helper for converting SafeArray to array of objects. + +package ole + +import ( + "unsafe" +) + +type SafeArrayConversion struct { + Array *SafeArray +} + +func (sac *SafeArrayConversion) ToStringArray() (strings []string) { + totalElements, _ := sac.TotalElements(0) + strings = make([]string, totalElements) + + for i := int32(0); i < totalElements; i++ { + strings[int32(i)], _ = safeArrayGetElementString(sac.Array, i) + } + + return +} + +func (sac *SafeArrayConversion) ToByteArray() (bytes []byte) { + totalElements, _ := sac.TotalElements(0) + bytes = make([]byte, totalElements) + + for i := int32(0); i < totalElements; i++ { + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&bytes[int32(i)])) + } + + return +} + +func (sac *SafeArrayConversion) ToValueArray() (values []interface{}) { + totalElements, _ := sac.TotalElements(0) + values = make([]interface{}, totalElements) + vt, _ := safeArrayGetVartype(sac.Array) + + for i := int32(0); i < totalElements; i++ { + switch VT(vt) { + case VT_BOOL: + var v bool + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_I1: + var v int8 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_I2: + var v int16 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_I4: + var v int32 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_I8: + var v int64 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_UI1: + var v uint8 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_UI2: + var v uint16 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_UI4: + var v uint32 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_UI8: + var v uint64 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_R4: + var v float32 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_R8: + var v float64 + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v + case VT_BSTR: + v , _ := safeArrayGetElementString(sac.Array, i) + values[i] = v + case VT_VARIANT: + var v VARIANT + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) + values[i] = v.Value() + v.Clear() + default: + // TODO + } + } + + return +} + +func (sac *SafeArrayConversion) GetType() (varType uint16, err error) { + return safeArrayGetVartype(sac.Array) +} + +func (sac *SafeArrayConversion) GetDimensions() (dimensions *uint32, err error) { + return safeArrayGetDim(sac.Array) +} + +func (sac *SafeArrayConversion) GetSize() (length *uint32, err error) { + return safeArrayGetElementSize(sac.Array) +} + +func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int32, err error) { + if index < 1 { + index = 1 + } + + // Get array bounds + var LowerBounds int32 + var UpperBounds int32 + + LowerBounds, err = safeArrayGetLBound(sac.Array, index) + if err != nil { + return + } + + UpperBounds, err = safeArrayGetUBound(sac.Array, index) + if err != nil { + return + } + + totalElements = UpperBounds - LowerBounds + 1 + return +} + +// Release Safe Array memory +func (sac *SafeArrayConversion) Release() { + safeArrayDestroy(sac.Array) +} diff --git a/vendor/github.com/go-ole/go-ole/safearrayslices.go b/vendor/github.com/go-ole/go-ole/safearrayslices.go new file mode 100644 index 0000000000..a9fa885f1d --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/safearrayslices.go @@ -0,0 +1,33 @@ +// +build windows + +package ole + +import ( + "unsafe" +) + +func safeArrayFromByteSlice(slice []byte) *SafeArray { + array, _ := safeArrayCreateVector(VT_UI1, 0, uint32(len(slice))) + + if array == nil { + panic("Could not convert []byte to SAFEARRAY") + } + + for i, v := range slice { + safeArrayPutElement(array, int64(i), uintptr(unsafe.Pointer(&v))) + } + return array +} + +func safeArrayFromStringSlice(slice []string) *SafeArray { + array, _ := safeArrayCreateVector(VT_BSTR, 0, uint32(len(slice))) + + if array == nil { + panic("Could not convert []string to SAFEARRAY") + } + // SysAllocStringLen(s) + for i, v := range slice { + safeArrayPutElement(array, int64(i), uintptr(unsafe.Pointer(SysAllocStringLen(v)))) + } + return array +} diff --git a/vendor/github.com/go-ole/go-ole/utility.go b/vendor/github.com/go-ole/go-ole/utility.go new file mode 100644 index 0000000000..99ee82dc34 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/utility.go @@ -0,0 +1,101 @@ +package ole + +import ( + "unicode/utf16" + "unsafe" +) + +// ClassIDFrom retrieves class ID whether given is program ID or application string. +// +// Helper that provides check against both Class ID from Program ID and Class ID from string. It is +// faster, if you know which you are using, to use the individual functions, but this will check +// against available functions for you. +func ClassIDFrom(programID string) (classID *GUID, err error) { + classID, err = CLSIDFromProgID(programID) + if err != nil { + classID, err = CLSIDFromString(programID) + if err != nil { + return + } + } + return +} + +// BytePtrToString converts byte pointer to a Go string. +func BytePtrToString(p *byte) string { + a := (*[10000]uint8)(unsafe.Pointer(p)) + i := 0 + for a[i] != 0 { + i++ + } + return string(a[:i]) +} + +// UTF16PtrToString is alias for LpOleStrToString. +// +// Kept for compatibility reasons. +func UTF16PtrToString(p *uint16) string { + return LpOleStrToString(p) +} + +// LpOleStrToString converts COM Unicode to Go string. +func LpOleStrToString(p *uint16) string { + if p == nil { + return "" + } + + length := lpOleStrLen(p) + a := make([]uint16, length) + + ptr := unsafe.Pointer(p) + + for i := 0; i < int(length); i++ { + a[i] = *(*uint16)(ptr) + ptr = unsafe.Pointer(uintptr(ptr) + 2) + } + + return string(utf16.Decode(a)) +} + +// BstrToString converts COM binary string to Go string. +func BstrToString(p *uint16) string { + if p == nil { + return "" + } + length := SysStringLen((*int16)(unsafe.Pointer(p))) + a := make([]uint16, length) + + ptr := unsafe.Pointer(p) + + for i := 0; i < int(length); i++ { + a[i] = *(*uint16)(ptr) + ptr = unsafe.Pointer(uintptr(ptr) + 2) + } + return string(utf16.Decode(a)) +} + +// lpOleStrLen returns the length of Unicode string. +func lpOleStrLen(p *uint16) (length int64) { + if p == nil { + return 0 + } + + ptr := unsafe.Pointer(p) + + for i := 0; ; i++ { + if 0 == *(*uint16)(ptr) { + length = int64(i) + break + } + ptr = unsafe.Pointer(uintptr(ptr) + 2) + } + return +} + +// convertHresultToError converts syscall to error, if call is unsuccessful. +func convertHresultToError(hr uintptr, r2 uintptr, ignore error) (err error) { + if hr != 0 { + err = NewError(hr) + } + return +} diff --git a/vendor/github.com/go-ole/go-ole/variables.go b/vendor/github.com/go-ole/go-ole/variables.go new file mode 100644 index 0000000000..a6add1b006 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variables.go @@ -0,0 +1,15 @@ +// +build windows + +package ole + +import ( + "golang.org/x/sys/windows" +) + +var ( + modcombase = windows.NewLazySystemDLL("combase.dll") + modkernel32 = windows.NewLazySystemDLL("kernel32.dll") + modole32 = windows.NewLazySystemDLL("ole32.dll") + modoleaut32 = windows.NewLazySystemDLL("oleaut32.dll") + moduser32 = windows.NewLazySystemDLL("user32.dll") +) diff --git a/vendor/github.com/go-ole/go-ole/variant.go b/vendor/github.com/go-ole/go-ole/variant.go new file mode 100644 index 0000000000..967a23fea9 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant.go @@ -0,0 +1,105 @@ +package ole + +import "unsafe" + +// NewVariant returns new variant based on type and value. +func NewVariant(vt VT, val int64) VARIANT { + return VARIANT{VT: vt, Val: val} +} + +// ToIUnknown converts Variant to Unknown object. +func (v *VARIANT) ToIUnknown() *IUnknown { + if v.VT != VT_UNKNOWN { + return nil + } + return (*IUnknown)(unsafe.Pointer(uintptr(v.Val))) +} + +// ToIDispatch converts variant to dispatch object. +func (v *VARIANT) ToIDispatch() *IDispatch { + if v.VT != VT_DISPATCH { + return nil + } + return (*IDispatch)(unsafe.Pointer(uintptr(v.Val))) +} + +// ToArray converts variant to SafeArray helper. +func (v *VARIANT) ToArray() *SafeArrayConversion { + if v.VT != VT_SAFEARRAY { + if v.VT&VT_ARRAY == 0 { + return nil + } + } + var safeArray *SafeArray = (*SafeArray)(unsafe.Pointer(uintptr(v.Val))) + return &SafeArrayConversion{safeArray} +} + +// ToString converts variant to Go string. +func (v *VARIANT) ToString() string { + if v.VT != VT_BSTR { + return "" + } + return BstrToString(*(**uint16)(unsafe.Pointer(&v.Val))) +} + +// Clear the memory of variant object. +func (v *VARIANT) Clear() error { + return VariantClear(v) +} + +// Value returns variant value based on its type. +// +// Currently supported types: 2- and 4-byte integers, strings, bools. +// Note that 64-bit integers, datetimes, and other types are stored as strings +// and will be returned as strings. +// +// Needs to be further converted, because this returns an interface{}. +func (v *VARIANT) Value() interface{} { + switch v.VT { + case VT_I1: + return int8(v.Val) + case VT_UI1: + return uint8(v.Val) + case VT_I2: + return int16(v.Val) + case VT_UI2: + return uint16(v.Val) + case VT_I4: + return int32(v.Val) + case VT_UI4: + return uint32(v.Val) + case VT_I8: + return int64(v.Val) + case VT_UI8: + return uint64(v.Val) + case VT_INT: + return int(v.Val) + case VT_UINT: + return uint(v.Val) + case VT_INT_PTR: + return uintptr(v.Val) // TODO + case VT_UINT_PTR: + return uintptr(v.Val) + case VT_R4: + return *(*float32)(unsafe.Pointer(&v.Val)) + case VT_R8: + return *(*float64)(unsafe.Pointer(&v.Val)) + case VT_BSTR: + return v.ToString() + case VT_DATE: + // VT_DATE type will either return float64 or time.Time. + d := uint64(v.Val) + date, err := GetVariantDate(d) + if err != nil { + return float64(v.Val) + } + return date + case VT_UNKNOWN: + return v.ToIUnknown() + case VT_DISPATCH: + return v.ToIDispatch() + case VT_BOOL: + return v.Val != 0 + } + return nil +} diff --git a/vendor/github.com/go-ole/go-ole/variant_386.go b/vendor/github.com/go-ole/go-ole/variant_386.go new file mode 100644 index 0000000000..e73736bf39 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_386.go @@ -0,0 +1,11 @@ +// +build 386 + +package ole + +type VARIANT struct { + VT VT // 2 + wReserved1 uint16 // 4 + wReserved2 uint16 // 6 + wReserved3 uint16 // 8 + Val int64 // 16 +} diff --git a/vendor/github.com/go-ole/go-ole/variant_amd64.go b/vendor/github.com/go-ole/go-ole/variant_amd64.go new file mode 100644 index 0000000000..dccdde1323 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_amd64.go @@ -0,0 +1,12 @@ +// +build amd64 + +package ole + +type VARIANT struct { + VT VT // 2 + wReserved1 uint16 // 4 + wReserved2 uint16 // 6 + wReserved3 uint16 // 8 + Val int64 // 16 + _ [8]byte // 24 +} diff --git a/vendor/github.com/go-ole/go-ole/variant_arm.go b/vendor/github.com/go-ole/go-ole/variant_arm.go new file mode 100644 index 0000000000..d472454443 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_arm.go @@ -0,0 +1,11 @@ +// +build arm + +package ole + +type VARIANT struct { + VT VT // 2 + wReserved1 uint16 // 4 + wReserved2 uint16 // 6 + wReserved3 uint16 // 8 + Val int64 // 16 +} diff --git a/vendor/github.com/go-ole/go-ole/variant_arm64.go b/vendor/github.com/go-ole/go-ole/variant_arm64.go new file mode 100644 index 0000000000..78473cec4f --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_arm64.go @@ -0,0 +1,13 @@ +//go:build arm64 +// +build arm64 + +package ole + +type VARIANT struct { + VT VT // 2 + wReserved1 uint16 // 4 + wReserved2 uint16 // 6 + wReserved3 uint16 // 8 + Val int64 // 16 + _ [8]byte // 24 +} diff --git a/vendor/github.com/go-ole/go-ole/variant_date_386.go b/vendor/github.com/go-ole/go-ole/variant_date_386.go new file mode 100644 index 0000000000..1b970f63f5 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_date_386.go @@ -0,0 +1,22 @@ +// +build windows,386 + +package ole + +import ( + "errors" + "syscall" + "time" + "unsafe" +) + +// GetVariantDate converts COM Variant Time value to Go time.Time. +func GetVariantDate(value uint64) (time.Time, error) { + var st syscall.Systemtime + v1 := uint32(value) + v2 := uint32(value >> 32) + r, _, _ := procVariantTimeToSystemTime.Call(uintptr(v1), uintptr(v2), uintptr(unsafe.Pointer(&st))) + if r != 0 { + return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil + } + return time.Now(), errors.New("Could not convert to time, passing current time.") +} diff --git a/vendor/github.com/go-ole/go-ole/variant_date_amd64.go b/vendor/github.com/go-ole/go-ole/variant_date_amd64.go new file mode 100644 index 0000000000..6952f1f0de --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_date_amd64.go @@ -0,0 +1,20 @@ +// +build windows,amd64 + +package ole + +import ( + "errors" + "syscall" + "time" + "unsafe" +) + +// GetVariantDate converts COM Variant Time value to Go time.Time. +func GetVariantDate(value uint64) (time.Time, error) { + var st syscall.Systemtime + r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st))) + if r != 0 { + return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil + } + return time.Now(), errors.New("Could not convert to time, passing current time.") +} diff --git a/vendor/github.com/go-ole/go-ole/variant_date_arm.go b/vendor/github.com/go-ole/go-ole/variant_date_arm.go new file mode 100644 index 0000000000..09ec7b5cfd --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_date_arm.go @@ -0,0 +1,22 @@ +// +build windows,arm + +package ole + +import ( + "errors" + "syscall" + "time" + "unsafe" +) + +// GetVariantDate converts COM Variant Time value to Go time.Time. +func GetVariantDate(value uint64) (time.Time, error) { + var st syscall.Systemtime + v1 := uint32(value) + v2 := uint32(value >> 32) + r, _, _ := procVariantTimeToSystemTime.Call(uintptr(v1), uintptr(v2), uintptr(unsafe.Pointer(&st))) + if r != 0 { + return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil + } + return time.Now(), errors.New("Could not convert to time, passing current time.") +} diff --git a/vendor/github.com/go-ole/go-ole/variant_date_arm64.go b/vendor/github.com/go-ole/go-ole/variant_date_arm64.go new file mode 100644 index 0000000000..02b04a0d4a --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_date_arm64.go @@ -0,0 +1,23 @@ +//go:build windows && arm64 +// +build windows,arm64 + +package ole + +import ( + "errors" + "syscall" + "time" + "unsafe" +) + +// GetVariantDate converts COM Variant Time value to Go time.Time. +func GetVariantDate(value uint64) (time.Time, error) { + var st syscall.Systemtime + v1 := uint32(value) + v2 := uint32(value >> 32) + r, _, _ := procVariantTimeToSystemTime.Call(uintptr(v1), uintptr(v2), uintptr(unsafe.Pointer(&st))) + if r != 0 { + return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil + } + return time.Now(), errors.New("Could not convert to time, passing current time.") +} diff --git a/vendor/github.com/go-ole/go-ole/variant_ppc64le.go b/vendor/github.com/go-ole/go-ole/variant_ppc64le.go new file mode 100644 index 0000000000..326427a7d1 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_ppc64le.go @@ -0,0 +1,12 @@ +// +build ppc64le + +package ole + +type VARIANT struct { + VT VT // 2 + wReserved1 uint16 // 4 + wReserved2 uint16 // 6 + wReserved3 uint16 // 8 + Val int64 // 16 + _ [8]byte // 24 +} diff --git a/vendor/github.com/go-ole/go-ole/variant_s390x.go b/vendor/github.com/go-ole/go-ole/variant_s390x.go new file mode 100644 index 0000000000..9874ca66b4 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/variant_s390x.go @@ -0,0 +1,12 @@ +// +build s390x + +package ole + +type VARIANT struct { + VT VT // 2 + wReserved1 uint16 // 4 + wReserved2 uint16 // 6 + wReserved3 uint16 // 8 + Val int64 // 16 + _ [8]byte // 24 +} diff --git a/vendor/github.com/go-ole/go-ole/vt_string.go b/vendor/github.com/go-ole/go-ole/vt_string.go new file mode 100644 index 0000000000..729b4a04dd --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/vt_string.go @@ -0,0 +1,58 @@ +// generated by stringer -output vt_string.go -type VT; DO NOT EDIT + +package ole + +import "fmt" + +const ( + _VT_name_0 = "VT_EMPTYVT_NULLVT_I2VT_I4VT_R4VT_R8VT_CYVT_DATEVT_BSTRVT_DISPATCHVT_ERRORVT_BOOLVT_VARIANTVT_UNKNOWNVT_DECIMAL" + _VT_name_1 = "VT_I1VT_UI1VT_UI2VT_UI4VT_I8VT_UI8VT_INTVT_UINTVT_VOIDVT_HRESULTVT_PTRVT_SAFEARRAYVT_CARRAYVT_USERDEFINEDVT_LPSTRVT_LPWSTR" + _VT_name_2 = "VT_RECORDVT_INT_PTRVT_UINT_PTR" + _VT_name_3 = "VT_FILETIMEVT_BLOBVT_STREAMVT_STORAGEVT_STREAMED_OBJECTVT_STORED_OBJECTVT_BLOB_OBJECTVT_CFVT_CLSID" + _VT_name_4 = "VT_BSTR_BLOBVT_VECTOR" + _VT_name_5 = "VT_ARRAY" + _VT_name_6 = "VT_BYREF" + _VT_name_7 = "VT_RESERVED" + _VT_name_8 = "VT_ILLEGAL" +) + +var ( + _VT_index_0 = [...]uint8{0, 8, 15, 20, 25, 30, 35, 40, 47, 54, 65, 73, 80, 90, 100, 110} + _VT_index_1 = [...]uint8{0, 5, 11, 17, 23, 28, 34, 40, 47, 54, 64, 70, 82, 91, 105, 113, 122} + _VT_index_2 = [...]uint8{0, 9, 19, 30} + _VT_index_3 = [...]uint8{0, 11, 18, 27, 37, 55, 71, 85, 90, 98} + _VT_index_4 = [...]uint8{0, 12, 21} + _VT_index_5 = [...]uint8{0, 8} + _VT_index_6 = [...]uint8{0, 8} + _VT_index_7 = [...]uint8{0, 11} + _VT_index_8 = [...]uint8{0, 10} +) + +func (i VT) String() string { + switch { + case 0 <= i && i <= 14: + return _VT_name_0[_VT_index_0[i]:_VT_index_0[i+1]] + case 16 <= i && i <= 31: + i -= 16 + return _VT_name_1[_VT_index_1[i]:_VT_index_1[i+1]] + case 36 <= i && i <= 38: + i -= 36 + return _VT_name_2[_VT_index_2[i]:_VT_index_2[i+1]] + case 64 <= i && i <= 72: + i -= 64 + return _VT_name_3[_VT_index_3[i]:_VT_index_3[i+1]] + case 4095 <= i && i <= 4096: + i -= 4095 + return _VT_name_4[_VT_index_4[i]:_VT_index_4[i+1]] + case i == 8192: + return _VT_name_5 + case i == 16384: + return _VT_name_6 + case i == 32768: + return _VT_name_7 + case i == 65535: + return _VT_name_8 + default: + return fmt.Sprintf("VT(%d)", i) + } +} diff --git a/vendor/github.com/go-ole/go-ole/winrt.go b/vendor/github.com/go-ole/go-ole/winrt.go new file mode 100644 index 0000000000..4e9eca7324 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/winrt.go @@ -0,0 +1,99 @@ +// +build windows + +package ole + +import ( + "reflect" + "syscall" + "unicode/utf8" + "unsafe" +) + +var ( + procRoInitialize = modcombase.NewProc("RoInitialize") + procRoActivateInstance = modcombase.NewProc("RoActivateInstance") + procRoGetActivationFactory = modcombase.NewProc("RoGetActivationFactory") + procWindowsCreateString = modcombase.NewProc("WindowsCreateString") + procWindowsDeleteString = modcombase.NewProc("WindowsDeleteString") + procWindowsGetStringRawBuffer = modcombase.NewProc("WindowsGetStringRawBuffer") +) + +func RoInitialize(thread_type uint32) (err error) { + hr, _, _ := procRoInitialize.Call(uintptr(thread_type)) + if hr != 0 { + err = NewError(hr) + } + return +} + +func RoActivateInstance(clsid string) (ins *IInspectable, err error) { + hClsid, err := NewHString(clsid) + if err != nil { + return nil, err + } + defer DeleteHString(hClsid) + + hr, _, _ := procRoActivateInstance.Call( + uintptr(unsafe.Pointer(hClsid)), + uintptr(unsafe.Pointer(&ins))) + if hr != 0 { + err = NewError(hr) + } + return +} + +func RoGetActivationFactory(clsid string, iid *GUID) (ins *IInspectable, err error) { + hClsid, err := NewHString(clsid) + if err != nil { + return nil, err + } + defer DeleteHString(hClsid) + + hr, _, _ := procRoGetActivationFactory.Call( + uintptr(unsafe.Pointer(hClsid)), + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(&ins))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// HString is handle string for pointers. +type HString uintptr + +// NewHString returns a new HString for Go string. +func NewHString(s string) (hstring HString, err error) { + u16 := syscall.StringToUTF16Ptr(s) + len := uint32(utf8.RuneCountInString(s)) + hr, _, _ := procWindowsCreateString.Call( + uintptr(unsafe.Pointer(u16)), + uintptr(len), + uintptr(unsafe.Pointer(&hstring))) + if hr != 0 { + err = NewError(hr) + } + return +} + +// DeleteHString deletes HString. +func DeleteHString(hstring HString) (err error) { + hr, _, _ := procWindowsDeleteString.Call(uintptr(hstring)) + if hr != 0 { + err = NewError(hr) + } + return +} + +// String returns Go string value of HString. +func (h HString) String() string { + var u16buf uintptr + var u16len uint32 + u16buf, _, _ = procWindowsGetStringRawBuffer.Call( + uintptr(h), + uintptr(unsafe.Pointer(&u16len))) + + u16hdr := reflect.SliceHeader{Data: u16buf, Len: int(u16len), Cap: int(u16len)} + u16 := *(*[]uint16)(unsafe.Pointer(&u16hdr)) + return syscall.UTF16ToString(u16) +} diff --git a/vendor/github.com/go-ole/go-ole/winrt_doc.go b/vendor/github.com/go-ole/go-ole/winrt_doc.go new file mode 100644 index 0000000000..52e6d74c9a --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/winrt_doc.go @@ -0,0 +1,36 @@ +// +build !windows + +package ole + +// RoInitialize +func RoInitialize(thread_type uint32) (err error) { + return NewError(E_NOTIMPL) +} + +// RoActivateInstance +func RoActivateInstance(clsid string) (ins *IInspectable, err error) { + return nil, NewError(E_NOTIMPL) +} + +// RoGetActivationFactory +func RoGetActivationFactory(clsid string, iid *GUID) (ins *IInspectable, err error) { + return nil, NewError(E_NOTIMPL) +} + +// HString is handle string for pointers. +type HString uintptr + +// NewHString returns a new HString for Go string. +func NewHString(s string) (hstring HString, err error) { + return HString(uintptr(0)), NewError(E_NOTIMPL) +} + +// DeleteHString deletes HString. +func DeleteHString(hstring HString) (err error) { + return NewError(E_NOTIMPL) +} + +// String returns Go string value of HString. +func (h HString) String() string { + return "" +} diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go deleted file mode 100644 index c6f66f1039..0000000000 --- a/vendor/github.com/golang/protobuf/jsonpb/decode.go +++ /dev/null @@ -1,531 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package jsonpb - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/encoding/protojson" - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapJSONUnmarshalV2 = false - -// UnmarshalNext unmarshals the next JSON object from d into m. -func UnmarshalNext(d *json.Decoder, m proto.Message) error { - return new(Unmarshaler).UnmarshalNext(d, m) -} - -// Unmarshal unmarshals a JSON object from r into m. -func Unmarshal(r io.Reader, m proto.Message) error { - return new(Unmarshaler).Unmarshal(r, m) -} - -// UnmarshalString unmarshals a JSON object from s into m. -func UnmarshalString(s string, m proto.Message) error { - return new(Unmarshaler).Unmarshal(strings.NewReader(s), m) -} - -// Unmarshaler is a configurable object for converting from a JSON -// representation to a protocol buffer object. -type Unmarshaler struct { - // AllowUnknownFields specifies whether to allow messages to contain - // unknown JSON fields, as opposed to failing to unmarshal. - AllowUnknownFields bool - - // AnyResolver is used to resolve the google.protobuf.Any well-known type. - // If unset, the global registry is used by default. - AnyResolver AnyResolver -} - -// JSONPBUnmarshaler is implemented by protobuf messages that customize the way -// they are unmarshaled from JSON. Messages that implement this should also -// implement JSONPBMarshaler so that the custom format can be produced. -// -// The JSON unmarshaling must follow the JSON to proto specification: -// -// https://developers.google.com/protocol-buffers/docs/proto3#json -// -// Deprecated: Custom types should implement protobuf reflection instead. -type JSONPBUnmarshaler interface { - UnmarshalJSONPB(*Unmarshaler, []byte) error -} - -// Unmarshal unmarshals a JSON object from r into m. -func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error { - return u.UnmarshalNext(json.NewDecoder(r), m) -} - -// UnmarshalNext unmarshals the next JSON object from d into m. -func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error { - if m == nil { - return errors.New("invalid nil message") - } - - // Parse the next JSON object from the stream. - raw := json.RawMessage{} - if err := d.Decode(&raw); err != nil { - return err - } - - // Check for custom unmarshalers first since they may not properly - // implement protobuf reflection that the logic below relies on. - if jsu, ok := m.(JSONPBUnmarshaler); ok { - return jsu.UnmarshalJSONPB(u, raw) - } - - mr := proto.MessageReflect(m) - - // NOTE: For historical reasons, a top-level null is treated as a noop. - // This is incorrect, but kept for compatibility. - if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" { - return nil - } - - if wrapJSONUnmarshalV2 { - // NOTE: If input message is non-empty, we need to preserve merge semantics - // of the old jsonpb implementation. These semantics are not supported by - // the protobuf JSON specification. - isEmpty := true - mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool { - isEmpty = false // at least one iteration implies non-empty - return false - }) - if !isEmpty { - // Perform unmarshaling into a newly allocated, empty message. - mr = mr.New() - - // Use a defer to copy all unmarshaled fields into the original message. - dst := proto.MessageReflect(m) - defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - dst.Set(fd, v) - return true - }) - } - - // Unmarshal using the v2 JSON unmarshaler. - opts := protojson.UnmarshalOptions{ - DiscardUnknown: u.AllowUnknownFields, - } - if u.AnyResolver != nil { - opts.Resolver = anyResolver{u.AnyResolver} - } - return opts.Unmarshal(raw, mr.Interface()) - } else { - if err := u.unmarshalMessage(mr, raw); err != nil { - return err - } - return protoV2.CheckInitialized(mr.Interface()) - } -} - -func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error { - md := m.Descriptor() - fds := md.Fields() - - if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok { - return jsu.UnmarshalJSONPB(u, in) - } - - if string(in) == "null" && md.FullName() != "google.protobuf.Value" { - return nil - } - - switch wellKnownType(md.FullName()) { - case "Any": - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return err - } - - rawTypeURL, ok := jsonObject["@type"] - if !ok { - return errors.New("Any JSON doesn't have '@type'") - } - typeURL, err := unquoteString(string(rawTypeURL)) - if err != nil { - return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL) - } - m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL)) - - var m2 protoreflect.Message - if u.AnyResolver != nil { - mi, err := u.AnyResolver.Resolve(typeURL) - if err != nil { - return err - } - m2 = proto.MessageReflect(mi) - } else { - mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) - if err != nil { - if err == protoregistry.NotFound { - return fmt.Errorf("could not resolve Any message type: %v", typeURL) - } - return err - } - m2 = mt.New() - } - - if wellKnownType(m2.Descriptor().FullName()) != "" { - rawValue, ok := jsonObject["value"] - if !ok { - return errors.New("Any JSON doesn't have 'value'") - } - if err := u.unmarshalMessage(m2, rawValue); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) - } - } else { - delete(jsonObject, "@type") - rawJSON, err := json.Marshal(jsonObject) - if err != nil { - return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) - } - if err = u.unmarshalMessage(m2, rawJSON); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) - } - } - - rawWire, err := protoV2.Marshal(m2.Interface()) - if err != nil { - return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err) - } - m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire)) - return nil - case "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue": - fd := fds.ByNumber(1) - v, err := u.unmarshalValue(m.NewField(fd), in, fd) - if err != nil { - return err - } - m.Set(fd, v) - return nil - case "Duration": - v, err := unquoteString(string(in)) - if err != nil { - return err - } - d, err := time.ParseDuration(v) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - - sec := d.Nanoseconds() / 1e9 - nsec := d.Nanoseconds() % 1e9 - m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) - m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) - return nil - case "Timestamp": - v, err := unquoteString(string(in)) - if err != nil { - return err - } - t, err := time.Parse(time.RFC3339Nano, v) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - - sec := t.Unix() - nsec := t.Nanosecond() - m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) - m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) - return nil - case "Value": - switch { - case string(in) == "null": - m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0)) - case string(in) == "true": - m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true)) - case string(in) == "false": - m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false)) - case hasPrefixAndSuffix('"', in, '"'): - s, err := unquoteString(string(in)) - if err != nil { - return fmt.Errorf("unrecognized type for Value %q", in) - } - m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s)) - case hasPrefixAndSuffix('[', in, ']'): - v := m.Mutable(fds.ByNumber(6)) - return u.unmarshalMessage(v.Message(), in) - case hasPrefixAndSuffix('{', in, '}'): - v := m.Mutable(fds.ByNumber(5)) - return u.unmarshalMessage(v.Message(), in) - default: - f, err := strconv.ParseFloat(string(in), 0) - if err != nil { - return fmt.Errorf("unrecognized type for Value %q", in) - } - m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f)) - } - return nil - case "ListValue": - var jsonArray []json.RawMessage - if err := json.Unmarshal(in, &jsonArray); err != nil { - return fmt.Errorf("bad ListValue: %v", err) - } - - lv := m.Mutable(fds.ByNumber(1)).List() - for _, raw := range jsonArray { - ve := lv.NewElement() - if err := u.unmarshalMessage(ve.Message(), raw); err != nil { - return err - } - lv.Append(ve) - } - return nil - case "Struct": - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return fmt.Errorf("bad StructValue: %v", err) - } - - mv := m.Mutable(fds.ByNumber(1)).Map() - for key, raw := range jsonObject { - kv := protoreflect.ValueOf(key).MapKey() - vv := mv.NewValue() - if err := u.unmarshalMessage(vv.Message(), raw); err != nil { - return fmt.Errorf("bad value in StructValue for key %q: %v", key, err) - } - mv.Set(kv, vv) - } - return nil - } - - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return err - } - - // Handle known fields. - for i := 0; i < fds.Len(); i++ { - fd := fds.Get(i) - if fd.IsWeak() && fd.Message().IsPlaceholder() { - continue // weak reference is not linked in - } - - // Search for any raw JSON value associated with this field. - var raw json.RawMessage - name := string(fd.Name()) - if fd.Kind() == protoreflect.GroupKind { - name = string(fd.Message().Name()) - } - if v, ok := jsonObject[name]; ok { - delete(jsonObject, name) - raw = v - } - name = string(fd.JSONName()) - if v, ok := jsonObject[name]; ok { - delete(jsonObject, name) - raw = v - } - - field := m.NewField(fd) - // Unmarshal the field value. - if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { - continue - } - v, err := u.unmarshalValue(field, raw, fd) - if err != nil { - return err - } - m.Set(fd, v) - } - - // Handle extension fields. - for name, raw := range jsonObject { - if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") { - continue - } - - // Resolve the extension field by name. - xname := protoreflect.FullName(name[len("[") : len(name)-len("]")]) - xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) - if xt == nil && isMessageSet(md) { - xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) - } - if xt == nil { - continue - } - delete(jsonObject, name) - fd := xt.TypeDescriptor() - if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { - return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName()) - } - - field := m.NewField(fd) - // Unmarshal the field value. - if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { - continue - } - v, err := u.unmarshalValue(field, raw, fd) - if err != nil { - return err - } - m.Set(fd, v) - } - - if !u.AllowUnknownFields && len(jsonObject) > 0 { - for name := range jsonObject { - return fmt.Errorf("unknown field %q in %v", name, md.FullName()) - } - } - return nil -} - -func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool { - if fd.Cardinality() == protoreflect.Repeated { - return false - } - if md := fd.Message(); md != nil { - return md.FullName() == "google.protobuf.Value" - } - if ed := fd.Enum(); ed != nil { - return ed.FullName() == "google.protobuf.NullValue" - } - return false -} - -func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool { - if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated { - _, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler) - return ok - } - return false -} - -func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - switch { - case fd.IsList(): - var jsonArray []json.RawMessage - if err := json.Unmarshal(in, &jsonArray); err != nil { - return v, err - } - lv := v.List() - for _, raw := range jsonArray { - ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd) - if err != nil { - return v, err - } - lv.Append(ve) - } - return v, nil - case fd.IsMap(): - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return v, err - } - kfd := fd.MapKey() - vfd := fd.MapValue() - mv := v.Map() - for key, raw := range jsonObject { - var kv protoreflect.MapKey - if kfd.Kind() == protoreflect.StringKind { - kv = protoreflect.ValueOf(key).MapKey() - } else { - v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd) - if err != nil { - return v, err - } - kv = v.MapKey() - } - - vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd) - if err != nil { - return v, err - } - mv.Set(kv, vv) - } - return v, nil - default: - return u.unmarshalSingularValue(v, in, fd) - } -} - -var nonFinite = map[string]float64{ - `"NaN"`: math.NaN(), - `"Infinity"`: math.Inf(+1), - `"-Infinity"`: math.Inf(-1), -} - -func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - switch fd.Kind() { - case protoreflect.BoolKind: - return unmarshalValue(in, new(bool)) - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: - return unmarshalValue(trimQuote(in), new(int32)) - case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - return unmarshalValue(trimQuote(in), new(int64)) - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: - return unmarshalValue(trimQuote(in), new(uint32)) - case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - return unmarshalValue(trimQuote(in), new(uint64)) - case protoreflect.FloatKind: - if f, ok := nonFinite[string(in)]; ok { - return protoreflect.ValueOfFloat32(float32(f)), nil - } - return unmarshalValue(trimQuote(in), new(float32)) - case protoreflect.DoubleKind: - if f, ok := nonFinite[string(in)]; ok { - return protoreflect.ValueOfFloat64(float64(f)), nil - } - return unmarshalValue(trimQuote(in), new(float64)) - case protoreflect.StringKind: - return unmarshalValue(in, new(string)) - case protoreflect.BytesKind: - return unmarshalValue(in, new([]byte)) - case protoreflect.EnumKind: - if hasPrefixAndSuffix('"', in, '"') { - vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in))) - if vd == nil { - return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName()) - } - return protoreflect.ValueOfEnum(vd.Number()), nil - } - return unmarshalValue(in, new(protoreflect.EnumNumber)) - case protoreflect.MessageKind, protoreflect.GroupKind: - err := u.unmarshalMessage(v.Message(), in) - return v, err - default: - panic(fmt.Sprintf("invalid kind %v", fd.Kind())) - } -} - -func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) { - err := json.Unmarshal(in, v) - return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err -} - -func unquoteString(in string) (out string, err error) { - err = json.Unmarshal([]byte(in), &out) - return out, err -} - -func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool { - if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix { - return true - } - return false -} - -// trimQuote is like unquoteString but simply strips surrounding quotes. -// This is incorrect, but is behavior done by the legacy implementation. -func trimQuote(in []byte) []byte { - if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' { - in = in[1 : len(in)-1] - } - return in -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/encode.go b/vendor/github.com/golang/protobuf/jsonpb/encode.go deleted file mode 100644 index e9438a93f3..0000000000 --- a/vendor/github.com/golang/protobuf/jsonpb/encode.go +++ /dev/null @@ -1,560 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package jsonpb - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "sort" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/encoding/protojson" - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapJSONMarshalV2 = false - -// Marshaler is a configurable object for marshaling protocol buffer messages -// to the specified JSON representation. -type Marshaler struct { - // OrigName specifies whether to use the original protobuf name for fields. - OrigName bool - - // EnumsAsInts specifies whether to render enum values as integers, - // as opposed to string values. - EnumsAsInts bool - - // EmitDefaults specifies whether to render fields with zero values. - EmitDefaults bool - - // Indent controls whether the output is compact or not. - // If empty, the output is compact JSON. Otherwise, every JSON object - // entry and JSON array value will be on its own line. - // Each line will be preceded by repeated copies of Indent, where the - // number of copies is the current indentation depth. - Indent string - - // AnyResolver is used to resolve the google.protobuf.Any well-known type. - // If unset, the global registry is used by default. - AnyResolver AnyResolver -} - -// JSONPBMarshaler is implemented by protobuf messages that customize the -// way they are marshaled to JSON. Messages that implement this should also -// implement JSONPBUnmarshaler so that the custom format can be parsed. -// -// The JSON marshaling must follow the proto to JSON specification: -// -// https://developers.google.com/protocol-buffers/docs/proto3#json -// -// Deprecated: Custom types should implement protobuf reflection instead. -type JSONPBMarshaler interface { - MarshalJSONPB(*Marshaler) ([]byte, error) -} - -// Marshal serializes a protobuf message as JSON into w. -func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error { - b, err := jm.marshal(m) - if len(b) > 0 { - if _, err := w.Write(b); err != nil { - return err - } - } - return err -} - -// MarshalToString serializes a protobuf message as JSON in string form. -func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) { - b, err := jm.marshal(m) - if err != nil { - return "", err - } - return string(b), nil -} - -func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) { - v := reflect.ValueOf(m) - if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { - return nil, errors.New("Marshal called with nil") - } - - // Check for custom marshalers first since they may not properly - // implement protobuf reflection that the logic below relies on. - if jsm, ok := m.(JSONPBMarshaler); ok { - return jsm.MarshalJSONPB(jm) - } - - if wrapJSONMarshalV2 { - opts := protojson.MarshalOptions{ - UseProtoNames: jm.OrigName, - UseEnumNumbers: jm.EnumsAsInts, - EmitUnpopulated: jm.EmitDefaults, - Indent: jm.Indent, - } - if jm.AnyResolver != nil { - opts.Resolver = anyResolver{jm.AnyResolver} - } - return opts.Marshal(proto.MessageReflect(m).Interface()) - } else { - // Check for unpopulated required fields first. - m2 := proto.MessageReflect(m) - if err := protoV2.CheckInitialized(m2.Interface()); err != nil { - return nil, err - } - - w := jsonWriter{Marshaler: jm} - err := w.marshalMessage(m2, "", "") - return w.buf, err - } -} - -type jsonWriter struct { - *Marshaler - buf []byte -} - -func (w *jsonWriter) write(s string) { - w.buf = append(w.buf, s...) -} - -func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error { - if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok { - b, err := jsm.MarshalJSONPB(w.Marshaler) - if err != nil { - return err - } - if typeURL != "" { - // we are marshaling this object to an Any type - var js map[string]*json.RawMessage - if err = json.Unmarshal(b, &js); err != nil { - return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err) - } - turl, err := json.Marshal(typeURL) - if err != nil { - return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) - } - js["@type"] = (*json.RawMessage)(&turl) - if b, err = json.Marshal(js); err != nil { - return err - } - } - w.write(string(b)) - return nil - } - - md := m.Descriptor() - fds := md.Fields() - - // Handle well-known types. - const secondInNanos = int64(time.Second / time.Nanosecond) - switch wellKnownType(md.FullName()) { - case "Any": - return w.marshalAny(m, indent) - case "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue": - fd := fds.ByNumber(1) - return w.marshalValue(fd, m.Get(fd), indent) - case "Duration": - const maxSecondsInDuration = 315576000000 - // "Generated output always contains 0, 3, 6, or 9 fractional digits, - // depending on required precision." - s := m.Get(fds.ByNumber(1)).Int() - ns := m.Get(fds.ByNumber(2)).Int() - if s < -maxSecondsInDuration || s > maxSecondsInDuration { - return fmt.Errorf("seconds out of range %v", s) - } - if ns <= -secondInNanos || ns >= secondInNanos { - return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) - } - if (s > 0 && ns < 0) || (s < 0 && ns > 0) { - return errors.New("signs of seconds and nanos do not match") - } - var sign string - if s < 0 || ns < 0 { - sign, s, ns = "-", -1*s, -1*ns - } - x := fmt.Sprintf("%s%d.%09d", sign, s, ns) - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, ".000") - w.write(fmt.Sprintf(`"%vs"`, x)) - return nil - case "Timestamp": - // "RFC 3339, where generated output will always be Z-normalized - // and uses 0, 3, 6 or 9 fractional digits." - s := m.Get(fds.ByNumber(1)).Int() - ns := m.Get(fds.ByNumber(2)).Int() - if ns < 0 || ns >= secondInNanos { - return fmt.Errorf("ns out of range [0, %v)", secondInNanos) - } - t := time.Unix(s, ns).UTC() - // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). - x := t.Format("2006-01-02T15:04:05.000000000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, ".000") - w.write(fmt.Sprintf(`"%vZ"`, x)) - return nil - case "Value": - // JSON value; which is a null, number, string, bool, object, or array. - od := md.Oneofs().Get(0) - fd := m.WhichOneof(od) - if fd == nil { - return errors.New("nil Value") - } - return w.marshalValue(fd, m.Get(fd), indent) - case "Struct", "ListValue": - // JSON object or array. - fd := fds.ByNumber(1) - return w.marshalValue(fd, m.Get(fd), indent) - } - - w.write("{") - if w.Indent != "" { - w.write("\n") - } - - firstField := true - if typeURL != "" { - if err := w.marshalTypeURL(indent, typeURL); err != nil { - return err - } - firstField = false - } - - for i := 0; i < fds.Len(); { - fd := fds.Get(i) - if od := fd.ContainingOneof(); od != nil { - fd = m.WhichOneof(od) - i += od.Fields().Len() - if fd == nil { - continue - } - } else { - i++ - } - - v := m.Get(fd) - - if !m.Has(fd) { - if !w.EmitDefaults || fd.ContainingOneof() != nil { - continue - } - if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) { - v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars - } - } - - if !firstField { - w.writeComma() - } - if err := w.marshalField(fd, v, indent); err != nil { - return err - } - firstField = false - } - - // Handle proto2 extensions. - if md.ExtensionRanges().Len() > 0 { - // Collect a sorted list of all extension descriptor and values. - type ext struct { - desc protoreflect.FieldDescriptor - val protoreflect.Value - } - var exts []ext - m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - if fd.IsExtension() { - exts = append(exts, ext{fd, v}) - } - return true - }) - sort.Slice(exts, func(i, j int) bool { - return exts[i].desc.Number() < exts[j].desc.Number() - }) - - for _, ext := range exts { - if !firstField { - w.writeComma() - } - if err := w.marshalField(ext.desc, ext.val, indent); err != nil { - return err - } - firstField = false - } - } - - if w.Indent != "" { - w.write("\n") - w.write(indent) - } - w.write("}") - return nil -} - -func (w *jsonWriter) writeComma() { - if w.Indent != "" { - w.write(",\n") - } else { - w.write(",") - } -} - -func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error { - // "If the Any contains a value that has a special JSON mapping, - // it will be converted as follows: {"@type": xxx, "value": yyy}. - // Otherwise, the value will be converted into a JSON object, - // and the "@type" field will be inserted to indicate the actual data type." - md := m.Descriptor() - typeURL := m.Get(md.Fields().ByNumber(1)).String() - rawVal := m.Get(md.Fields().ByNumber(2)).Bytes() - - var m2 protoreflect.Message - if w.AnyResolver != nil { - mi, err := w.AnyResolver.Resolve(typeURL) - if err != nil { - return err - } - m2 = proto.MessageReflect(mi) - } else { - mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) - if err != nil { - return err - } - m2 = mt.New() - } - - if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil { - return err - } - - if wellKnownType(m2.Descriptor().FullName()) == "" { - return w.marshalMessage(m2, indent, typeURL) - } - - w.write("{") - if w.Indent != "" { - w.write("\n") - } - if err := w.marshalTypeURL(indent, typeURL); err != nil { - return err - } - w.writeComma() - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - w.write(`"value": `) - } else { - w.write(`"value":`) - } - if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil { - return err - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - } - w.write("}") - return nil -} - -func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error { - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - } - w.write(`"@type":`) - if w.Indent != "" { - w.write(" ") - } - b, err := json.Marshal(typeURL) - if err != nil { - return err - } - w.write(string(b)) - return nil -} - -// marshalField writes field description and value to the Writer. -func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - } - w.write(`"`) - switch { - case fd.IsExtension(): - // For message set, use the fname of the message as the extension name. - name := string(fd.FullName()) - if isMessageSet(fd.ContainingMessage()) { - name = strings.TrimSuffix(name, ".message_set_extension") - } - - w.write("[" + name + "]") - case w.OrigName: - name := string(fd.Name()) - if fd.Kind() == protoreflect.GroupKind { - name = string(fd.Message().Name()) - } - w.write(name) - default: - w.write(string(fd.JSONName())) - } - w.write(`":`) - if w.Indent != "" { - w.write(" ") - } - return w.marshalValue(fd, v, indent) -} - -func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - switch { - case fd.IsList(): - w.write("[") - comma := "" - lv := v.List() - for i := 0; i < lv.Len(); i++ { - w.write(comma) - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - w.write(w.Indent) - } - if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil { - return err - } - comma = "," - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - } - w.write("]") - return nil - case fd.IsMap(): - kfd := fd.MapKey() - vfd := fd.MapValue() - mv := v.Map() - - // Collect a sorted list of all map keys and values. - type entry struct{ key, val protoreflect.Value } - var entries []entry - mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { - entries = append(entries, entry{k.Value(), v}) - return true - }) - sort.Slice(entries, func(i, j int) bool { - switch kfd.Kind() { - case protoreflect.BoolKind: - return !entries[i].key.Bool() && entries[j].key.Bool() - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - return entries[i].key.Int() < entries[j].key.Int() - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - return entries[i].key.Uint() < entries[j].key.Uint() - case protoreflect.StringKind: - return entries[i].key.String() < entries[j].key.String() - default: - panic("invalid kind") - } - }) - - w.write(`{`) - comma := "" - for _, entry := range entries { - w.write(comma) - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - w.write(w.Indent) - } - - s := fmt.Sprint(entry.key.Interface()) - b, err := json.Marshal(s) - if err != nil { - return err - } - w.write(string(b)) - - w.write(`:`) - if w.Indent != "" { - w.write(` `) - } - - if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil { - return err - } - comma = "," - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - } - w.write(`}`) - return nil - default: - return w.marshalSingularValue(fd, v, indent) - } -} - -func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - switch { - case !v.IsValid(): - w.write("null") - return nil - case fd.Message() != nil: - return w.marshalMessage(v.Message(), indent+w.Indent, "") - case fd.Enum() != nil: - if fd.Enum().FullName() == "google.protobuf.NullValue" { - w.write("null") - return nil - } - - vd := fd.Enum().Values().ByNumber(v.Enum()) - if vd == nil || w.EnumsAsInts { - w.write(strconv.Itoa(int(v.Enum()))) - } else { - w.write(`"` + string(vd.Name()) + `"`) - } - return nil - default: - switch v.Interface().(type) { - case float32, float64: - switch { - case math.IsInf(v.Float(), +1): - w.write(`"Infinity"`) - return nil - case math.IsInf(v.Float(), -1): - w.write(`"-Infinity"`) - return nil - case math.IsNaN(v.Float()): - w.write(`"NaN"`) - return nil - } - case int64, uint64: - w.write(fmt.Sprintf(`"%d"`, v.Interface())) - return nil - } - - b, err := json.Marshal(v.Interface()) - if err != nil { - return err - } - w.write(string(b)) - return nil - } -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/json.go b/vendor/github.com/golang/protobuf/jsonpb/json.go deleted file mode 100644 index 480e2448de..0000000000 --- a/vendor/github.com/golang/protobuf/jsonpb/json.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package jsonpb provides functionality to marshal and unmarshal between a -// protocol buffer message and JSON. It follows the specification at -// https://developers.google.com/protocol-buffers/docs/proto3#json. -// -// Do not rely on the default behavior of the standard encoding/json package -// when called on generated message types as it does not operate correctly. -// -// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson" -// package instead. -package jsonpb - -import ( - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/runtime/protoimpl" -) - -// AnyResolver takes a type URL, present in an Any message, -// and resolves it into an instance of the associated message. -type AnyResolver interface { - Resolve(typeURL string) (proto.Message, error) -} - -type anyResolver struct{ AnyResolver } - -func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) { - return r.FindMessageByURL(string(message)) -} - -func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) { - m, err := r.Resolve(url) - if err != nil { - return nil, err - } - return protoimpl.X.MessageTypeOf(m), nil -} - -func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { - return protoregistry.GlobalTypes.FindExtensionByName(field) -} - -func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { - return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) -} - -func wellKnownType(s protoreflect.FullName) string { - if s.Parent() == "google.protobuf" { - switch s.Name() { - case "Empty", "Any", - "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue", - "Duration", "Timestamp", - "NullValue", "Struct", "Value", "ListValue": - return string(s.Name()) - } - } - return "" -} - -func isMessageSet(md protoreflect.MessageDescriptor) bool { - ms, ok := md.(interface{ IsMessageSet() bool }) - return ok && ms.IsMessageSet() -} diff --git a/vendor/github.com/longhorn/go-common-libs/LICENSE b/vendor/github.com/longhorn/go-common-libs/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/longhorn/go-common-libs/exec/exec.go b/vendor/github.com/longhorn/go-common-libs/exec/exec.go new file mode 100644 index 0000000000..8efd15d450 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/exec/exec.go @@ -0,0 +1,125 @@ +package exec + +import ( + "bytes" + "context" + "io" + "os" + "os/exec" + "strings" + "time" + + "github.com/pkg/errors" + + "github.com/longhorn/go-common-libs/types" +) + +// ExecuteInterface is the interface for executing commands. +type ExecuteInterface interface { + Execute(envs []string, binary string, args []string, timeout time.Duration) (string, error) + ExecuteWithStdin(binary string, args []string, stdinString string, timeout time.Duration) (string, error) + ExecuteWithStdinPipe(binary string, args []string, stdinString string, timeout time.Duration) (string, error) +} + +// NewExecutor returns a new Executor. +func NewExecutor() ExecuteInterface { + return &Executor{} +} + +// Executor is the implementation of ExecuteInterface. +type Executor struct{} + +// Execute executes the given command with the specified environment variables, binary, and arguments. +// It returns the command's output and any occurred error. +func (e *Executor) Execute(envs []string, binary string, args []string, timeout time.Duration) (string, error) { + // If the timeout is set to -1, execute the command without any timeout. + // Otherwise, execute the command with the specified timeout. + switch timeout { + case types.ExecuteNoTimeout: + return e.executeWithoutTimeout(envs, binary, args) + default: + return e.executeWithTimeout(envs, binary, args, timeout) + } +} + +// ExecuteWithTimeout executes the command with timeout. +func (e *Executor) executeWithTimeout(envs []string, binary string, args []string, timeout time.Duration) (string, error) { + cmd := exec.Command(binary, args...) + cmd.Env = append(os.Environ(), envs...) + return e.executeCmd(cmd, timeout) +} + +// ExecuteWithoutTimeout executes the command without timeout. +func (e *Executor) executeWithoutTimeout(envs []string, binary string, args []string) (string, error) { + cmd := exec.Command(binary, args...) + cmd.Env = append(os.Environ(), envs...) + + var output, stderr bytes.Buffer + cmd.Stdout = &output + cmd.Stderr = &stderr + + if err := cmd.Run(); err != nil { + return output.String(), errors.Wrapf(err, "failed to execute: %v %v, output %s, stderr %s", + binary, args, output.String(), stderr.String()) + } + return output.String(), nil +} + +// executeCmd executes the command with timeout. If timeout is 0, it will use default timeout. +func (e *Executor) executeCmd(cmd *exec.Cmd, timeout time.Duration) (string, error) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + var output, stderr bytes.Buffer + cmd.Stdout = &output + cmd.Stderr = &stderr + + errChan := make(chan error, 1) + go func() { + errChan <- cmd.Run() + }() + + select { + case err := <-errChan: + if err != nil { + return "", errors.Wrapf(err, "failed to execute: %v %v, output %s, stderr %s", + cmd.Path, cmd.Args, output.String(), stderr.String()) + } + case <-ctx.Done(): + return "", errors.Errorf("timeout executing: %v %v", cmd.Path, cmd.Args) + } + + return output.String(), nil +} + +// ExecuteWithStdin executes the command with stdin. +func (e *Executor) ExecuteWithStdin(binary string, args []string, stdinString string, timeout time.Duration) (string, error) { + cmd := exec.Command(binary, args...) + cmd.Env = os.Environ() + + if stdinString != "" { + cmd.Stdin = strings.NewReader(stdinString) + } + + return e.executeCmd(cmd, timeout) +} + +// ExecuteWithStdinPipe executes the command with stdin pipe. +func (e *Executor) ExecuteWithStdinPipe(binary string, args []string, stdinString string, timeout time.Duration) (string, error) { + cmd := exec.Command(binary, args...) + cmd.Env = os.Environ() + + stdin, err := cmd.StdinPipe() + if err != nil { + return "", err + } + + go func() { + defer func() { + _ = stdin.Close() + }() + _, _ = io.WriteString(stdin, stdinString) + }() + + return e.executeCmd(cmd, timeout) +} diff --git a/vendor/github.com/longhorn/go-common-libs/io/file.go b/vendor/github.com/longhorn/go-common-libs/io/file.go new file mode 100644 index 0000000000..945be4d786 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/io/file.go @@ -0,0 +1,243 @@ +package io + +import ( + "fmt" + "io" + "os" + "path/filepath" + "syscall" + "time" + + "github.com/pkg/errors" + "github.com/shirou/gopsutil/v3/disk" + "github.com/sirupsen/logrus" + + "github.com/longhorn/go-common-libs/types" +) + +// CreateDirectory creates a directory at the specified path, and sets the modification time. +func CreateDirectory(path string, modTime time.Time) (string, error) { + // Check if the directory already exists + if fileInfo, err := os.Stat(path); err == nil && fileInfo.IsDir() { + return filepath.Abs(path) + } + + // Create the directory and its parent directories if they don't exist. + err := os.MkdirAll(path, 0755) + if err != nil { + return "", err + } + + // Set the modification time of the directory. + err = os.Chtimes(path, modTime, modTime) + if err != nil { + return "", errors.Wrapf(err, "failed to set the modification time for %v", path) + } + + // Return the absolute path of the directory. + return filepath.Abs(path) +} + +// CopyDirectory copies the directory from source to destination. +func CopyDirectory(sourcePath, destinationPath string, doOverWrite bool) error { + var err error + defer func() { + err = errors.Wrapf(err, "failed to copy directory %v to %v", sourcePath, destinationPath) + }() + + sourcePathInfo, err := os.Stat(sourcePath) + if err != nil { + return err + } + + destinationAbsPath, err := CreateDirectory(destinationPath, sourcePathInfo.ModTime()) + if err != nil { + return err + } + + return CopyFiles(sourcePath, destinationAbsPath, doOverWrite) +} + +// CopyFiles copies the files from source to destination. +func CopyFiles(sourcePath, destinationPath string, doOverWrite bool) error { + srcFileInfo, err := os.Stat(sourcePath) + if err != nil { + return err + } + + if !srcFileInfo.IsDir() { + return CopyFile(sourcePath, destinationPath, doOverWrite) + } + + srcFileInfos, err := os.ReadDir(sourcePath) + if err != nil { + return errors.Wrapf(err, "failed to read source directory %v", sourcePath) + } + + for _, srcFileInfo := range srcFileInfos { + srcFileInfo, err := srcFileInfo.Info() + if err != nil { + return err + } + + dstFilePath := filepath.Join(destinationPath, srcFileInfo.Name()) + srcFilePath := filepath.Join(sourcePath, srcFileInfo.Name()) + + if srcFileInfo.IsDir() { + if err := CopyDirectory(srcFilePath, dstFilePath, doOverWrite); err != nil { + return err + } + } else { + if err := CopyFile(srcFilePath, dstFilePath, doOverWrite); err != nil { + return err + } + } + } + + return nil +} + +// CopyFile copies the file from source to destination. +func CopyFile(sourcePath, destinationPath string, overWrite bool) error { + var err error + defer func() { + err = errors.Wrapf(err, "failed to copy file %v to %v", sourcePath, destinationPath) + }() + + sourceFileInfo, err := os.Stat(sourcePath) + if err != nil { + return err + } + + if !overWrite { + if _, err := os.Stat(destinationPath); err == nil { + logrus.Warnf("destination file %v already exists", destinationPath) + return nil + } + } + + sourceFile, err := os.Open(sourcePath) + if err != nil { + return err + } + defer sourceFile.Close() + + _, err = CreateDirectory(filepath.Dir(destinationPath), sourceFileInfo.ModTime()) + if err != nil { + return err + } + + destinationFile, err := os.Create(destinationPath) + if err != nil { + return err + } + defer destinationFile.Close() + + _, err = io.Copy(destinationFile, sourceFile) + if err != nil { + return err + } + + // Set the modification time of the file. + sourceFileModTime := sourceFileInfo.ModTime() + return os.Chtimes(destinationPath, sourceFileModTime, sourceFileModTime) +} + +// GetEmptyFiles retrieves a list of paths for all empty files within the specified directory. +// It uses filepath.Walk to traverse the directory and finds files with zero size. +// It returns a slice of filePaths and an error if any. +func GetEmptyFiles(directory string) (filePaths []string, err error) { + err = filepath.Walk(directory, func(path string, info os.FileInfo, err error) error { + if err != nil { + return errors.Wrapf(err, "failed to walk directory %v", directory) + } + if info.IsDir() { + return nil + } + if info.Size() == 0 { + filePaths = append(filePaths, path) + } + return nil + }) + return filePaths, errors.Wrapf(err, "failed to get empty files in %s", directory) +} + +// FindFiles searches for files in the specified directory with the given fileName. +// If fileName is empty, it retrieves all files in the directory. +// It returns a slice of filePaths and an error if any. +func FindFiles(directory, fileName string) (filePaths []string, err error) { + err = filepath.Walk(directory, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if fileName == "" || info.Name() == fileName { + filePaths = append(filePaths, path) + } + return nil + }) + return filePaths, errors.Wrapf(err, "failed to find files in %s", directory) +} + +// ReadFileContent reads the content of the file. +func ReadFileContent(filePath string) (string, error) { + if _, err := os.Stat(filePath); err != nil { + return "", errors.Wrapf(err, "cannot find file %v", filePath) + } + + content, err := os.ReadFile(filePath) + if err != nil { + return "", err + } + + return string(content), nil +} + +// SyncFile syncs the file to the disk. +func SyncFile(filePath string) error { + file, err := os.OpenFile(filePath, os.O_RDWR, 0644) + if err != nil { + return err + } + defer file.Close() + + return file.Sync() +} + +// GetDiskStat returns the disk stat for the specified path. +func GetDiskStat(path string) (diskStat types.DiskStat, err error) { + defer func() { + err = errors.Wrapf(err, "failed to get fs stat for %v", path) + }() + + var statfs syscall.Statfs_t + if err := syscall.Statfs(path, &statfs); err != nil { + return diskStat, err + } + + usage, err := disk.Usage(path) + if err != nil { + return diskStat, err + } + + // Convert the FSID components to a single uint64 FSID value + var fsidValue uint64 + for _, component := range statfs.Fsid.X__val { + // Combine components using bit manipulation + fsidValue = (fsidValue << 32) | uint64(uint32(component)) + } + + // Format the FSID value with leading zeros + fsidFormatted := fmt.Sprintf("%012x", fsidValue) + + return types.DiskStat{ + DiskID: fsidFormatted, + Path: path, + Type: usage.Fstype, + Driver: types.DiskDriverNone, + FreeBlocks: int64(statfs.Bfree), + TotalBlocks: int64(statfs.Blocks), + BlockSize: statfs.Bsize, + StorageMaximum: int64(statfs.Blocks) * statfs.Bsize, + StorageAvailable: int64(statfs.Bfree) * statfs.Bsize, + }, nil +} diff --git a/vendor/github.com/longhorn/go-common-libs/ns/crypto.go b/vendor/github.com/longhorn/go-common-libs/ns/crypto.go new file mode 100644 index 0000000000..5638b37dde --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/ns/crypto.go @@ -0,0 +1,69 @@ +package ns + +import ( + "time" + + "github.com/longhorn/go-common-libs/types" +) + +// LuksOpen runs cryptsetup luksOpen with the given passphrase and +// returns the stdout and error. +func (nsexec *Executor) LuksOpen(volume, devicePath, passphrase string, timeout time.Duration) (stdout string, err error) { + args := []string{"luksOpen", devicePath, volume, "-d", "/dev/stdin"} + return nsexec.CryptsetupWithPassphrase(passphrase, args, timeout) +} + +// LuksClose runs cryptsetup luksClose and returns the stdout and error. +func (nsexec *Executor) LuksClose(volume string, timeout time.Duration) (stdout string, err error) { + args := []string{"luksClose", volume} + return nsexec.Cryptsetup(args, timeout) +} + +// LuksFormat runs cryptsetup luksFormat with the given passphrase and +// returns the stdout and error. +func (nsexec *Executor) LuksFormat(devicePath, passphrase, keyCipher, keyHash, keySize, pbkdf string, timeout time.Duration) (stdout string, err error) { + args := []string{ + "-q", "luksFormat", + "--type", "luks2", + "--cipher", keyCipher, + "--hash", keyHash, + "--key-size", keySize, + "--pbkdf", pbkdf, + devicePath, "-d", "/dev/stdin", + } + return nsexec.CryptsetupWithPassphrase(passphrase, args, timeout) +} + +// LuksResize runs cryptsetup resize with the given passphrase and +// returns the stdout and error. +func (nsexec *Executor) LuksResize(volume, passphrase string, timeout time.Duration) (stdout string, err error) { + args := []string{"resize", volume} + return nsexec.CryptsetupWithPassphrase(passphrase, args, timeout) +} + +// LuksStatus runs cryptsetup status and returns the stdout and error. +func (nsexec *Executor) LuksStatus(volume string, timeout time.Duration) (stdout string, err error) { + args := []string{"status", volume} + return nsexec.Cryptsetup(args, timeout) +} + +// Cryptsetup runs cryptsetup without passphrase. It will return +// 0 on success and a non-zero value on error. +func (nsexec *Executor) Cryptsetup(args []string, timeout time.Duration) (stdout string, err error) { + return nsexec.CryptsetupWithPassphrase("", args, timeout) +} + +// CryptsetupWithPassphrase runs cryptsetup with passphrase. It will return +// 0 on success and a non-zero value on error. +// 1 wrong parameters, 2 no permission (bad passphrase), +// 3 out of memory, 4 wrong device specified, +// 5 device already exists or device is busy. +func (nsexec *Executor) CryptsetupWithPassphrase(passphrase string, args []string, timeout time.Duration) (stdout string, err error) { + // NOTE: When using cryptsetup, ensure it is run in the host IPC/MNT namespace. + // If only the MNT namespace is used, the binary will not return, but the + // appropriate action will still be performed. + // For Talos Linux, cryptsetup comes pre-installed in the host namespace + // (ref: https://github.com/siderolabs/pkgs/blob/release-1.4/reproducibility/pkg.yaml#L10) + // for the [Disk Encryption](https://www.talos.dev/v1.4/talos-guides/configuration/disk-encryption/). + return nsexec.ExecuteWithStdin(nil, types.BinaryCryptsetup, args, passphrase, timeout) +} diff --git a/vendor/github.com/longhorn/go-common-libs/ns/executor.go b/vendor/github.com/longhorn/go-common-libs/ns/executor.go new file mode 100644 index 0000000000..a850e7710c --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/ns/executor.go @@ -0,0 +1,87 @@ +package ns + +import ( + "path/filepath" + "time" + + "github.com/pkg/errors" + + "github.com/longhorn/go-common-libs/exec" + "github.com/longhorn/go-common-libs/proc" + "github.com/longhorn/go-common-libs/types" +) + +// Executor is a struct resonpsible for executing commands in a specific +// namespace using nsenter. +type Executor struct { + namespaces []types.Namespace // The namespaces to enter. + nsDirectory string // The directory of the namespace. + + executor exec.ExecuteInterface // An interface for executing commands. This allows mocking for unit tests. +} + +// NewNamespaceExecutor creates a new namespace executor for the given process name, +// namespaces and proc directory. If the process name is not empty, it will try to +// use the process namespace directory. Otherwise, it will use the host namespace +// directory. The namespaces are the namespaces to enter. The proc directory is +// the directory where the process information is stored. It will also verify the +// existence of the nsenter binary. +func NewNamespaceExecutor(processName, procDirectory string, namespaces []types.Namespace) (*Executor, error) { + nsDir, err := proc.GetProcessNamespaceDirectory(processName, procDirectory) + if err != nil { + return nil, err + } + + NamespaceExecutor := &Executor{ + namespaces: namespaces, + nsDirectory: nsDir, + executor: exec.NewExecutor(), + } + + if _, err := NamespaceExecutor.executor.Execute(nil, types.NsBinary, []string{"-V"}, types.ExecuteDefaultTimeout); err != nil { + return nil, errors.Wrap(err, "cannot find nsenter for namespace switching") + } + + return NamespaceExecutor, nil +} + +// prepareCommandArgs prepares the nsenter command arguments. +func (nsexec *Executor) prepareCommandArgs(binary string, args, envs []string) []string { + cmdArgs := []string{} + for _, ns := range nsexec.namespaces { + nsPath := filepath.Join(nsexec.nsDirectory, ns.String()) + switch ns { + case types.NamespaceIpc: + cmdArgs = append(cmdArgs, "--ipc="+nsPath) + case types.NamespaceMnt: + cmdArgs = append(cmdArgs, "--mount="+nsPath) + case types.NamespaceNet: + cmdArgs = append(cmdArgs, "--net="+nsPath) + } + } + if len(envs) > 0 { + cmdArgs = append(cmdArgs, "env", "-i") + cmdArgs = append(cmdArgs, envs...) + } + + cmdArgs = append(cmdArgs, binary) + return append(cmdArgs, args...) +} + +// Execute executes the command in the namespace. If NsDirectory is empty, +// it will execute the command in the current namespace. +func (nsexec *Executor) Execute(envs []string, binary string, args []string, timeout time.Duration) (string, error) { + return nsexec.executor.Execute(nil, types.NsBinary, nsexec.prepareCommandArgs(binary, args, envs), timeout) +} + +// ExecuteWithStdin executes the command in the namespace with stdin. +// If NsDirectory is empty, it will execute the command in the current namespace. +func (nsexec *Executor) ExecuteWithStdin(envs []string, binary string, args []string, stdinString string, timeout time.Duration) (string, error) { + return nsexec.executor.ExecuteWithStdin(types.NsBinary, nsexec.prepareCommandArgs(binary, args, envs), stdinString, timeout) +} + +// ExecuteWithStdinPipe executes the command in the namespace with stdin pipe. +// If NsDirectory is empty, it will execute the command in the current namespace. +func (nsexec *Executor) ExecuteWithStdinPipe(envs []string, binary string, args []string, stdinString string, timeout time.Duration) (string, error) { + return nsexec.executor.ExecuteWithStdinPipe(types.NsBinary, nsexec.prepareCommandArgs(binary, args, envs), stdinString, timeout) +} diff --git a/vendor/github.com/longhorn/go-common-libs/ns/file.go b/vendor/github.com/longhorn/go-common-libs/ns/file.go new file mode 100644 index 0000000000..26fe10c5d9 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/ns/file.go @@ -0,0 +1,282 @@ +package ns + +import ( + "io/fs" + "os" + "path/filepath" + "strings" + "time" + + "github.com/pkg/errors" + + "github.com/longhorn/go-common-libs/io" + "github.com/longhorn/go-common-libs/types" +) + +// CopyDirectory switches to the host namespace and copies the content from +// source to destination. It will overwrite the destination if overWrite is true. +// Top level directory is prohibited. +func CopyDirectory(source, destination string, overWrite bool) (err error) { + defer func() { + err = errors.Wrapf(err, "failed to copy host content from %v to %v", source, destination) + }() + + srcDir, err := filepath.Abs(filepath.Clean(source)) + if err != nil { + return err + } + + dstDir, err := filepath.Abs(filepath.Clean(destination)) + if err != nil { + return err + } + + if strings.Count(srcDir, "/") < 2 || strings.Count(dstDir, "/") < 2 { + return errors.Errorf("prohibit copying the content for the top level of directory %v or %v", srcDir, dstDir) + } + + fn := func() (interface{}, error) { + return "", io.CopyFiles(source, destination, overWrite) + } + + _, err = RunFunc(fn, 0) + return err +} + +// CreateDirectory switches to the host namespace and creates a directory at +// the specified path. +func CreateDirectory(path string, modTime time.Time) (result string, err error) { + defer func() { + err = errors.Wrapf(err, "failed to create directory %s", path) + }() + + fn := func() (interface{}, error) { + return io.CreateDirectory(path, modTime) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return "", err + } + + var ableToCast bool + result, ableToCast = rawResult.(string) + if !ableToCast { + return "", errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} + +// DeleteDirectory switches to the host namespace and removes the directory +// at the specified path. +func DeleteDirectory(directory string) (err error) { + defer func() { + err = errors.Wrapf(err, "failed to remove host directory %v", directory) + }() + + dir, err := filepath.Abs(filepath.Clean(directory)) + if err != nil { + return err + } + + if strings.Count(dir, "/") < 2 { + return errors.Errorf("prohibit removing the top level of directory %v", dir) + } + + fn := func() (interface{}, error) { + if _, err := os.Stat(dir); err != nil { + if os.IsNotExist(err) { + return nil, nil + } + return nil, err + } + + return nil, os.RemoveAll(dir) + } + + _, err = RunFunc(fn, 0) + return err +} + +// ReadDirectory switches to the host namespace and reads the content of the +// directory at the specified path. +func ReadDirectory(directory string) (result []fs.DirEntry, err error) { + defer func() { + err = errors.Wrapf(err, "failed to read directory %s", directory) + }() + + fn := func() (interface{}, error) { + return os.ReadDir(directory) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return nil, err + } + + var ableToCast bool + result, ableToCast = rawResult.([]fs.DirEntry) + if !ableToCast { + return nil, errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} + +// CopyFiles switches to the host namespace and copies the all files from +// source to destination. It will overwrite the destination if overWrite is true. +func CopyFiles(sourcePath, destinationPath string, doOverWrite bool) (err error) { + defer func() { + err = errors.Wrapf(err, "failed to copy files from %s to %s", sourcePath, destinationPath) + }() + + fn := func() (interface{}, error) { + return "", io.CopyFiles(sourcePath, destinationPath, doOverWrite) + } + + _, err = RunFunc(fn, 0) + return err +} + +// GetEmptyFiles switches to the host namespace and retrieves a list +// of paths for all empty files within the specified directory. +func GetEmptyFiles(directory string) (result []string, err error) { + defer func() { + err = errors.Wrapf(err, "failed to get empty files in %s", directory) + }() + + fn := func() (interface{}, error) { + return io.GetEmptyFiles(directory) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return nil, err + } + + var ableToCast bool + result, ableToCast = rawResult.([]string) + if !ableToCast { + return nil, errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} + +// GetFileInfo switches to the host namespace and returns the file info of +// the file at the specified path. +func GetFileInfo(path string) (result fs.FileInfo, err error) { + defer func() { + err = errors.Wrapf(err, "failed to get file info of %s", path) + }() + + fn := func() (interface{}, error) { + return os.Stat(path) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return nil, err + } + + var ableToCast bool + result, ableToCast = rawResult.(fs.FileInfo) + if !ableToCast { + return nil, errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} + +// ReadFileContent switches to the host namespace and returns the content of +// the file at the specified path. +func ReadFileContent(filePath string) (result string, err error) { + defer func() { + err = errors.Wrapf(err, "failed to read file content of %s", filePath) + }() + + fn := func() (interface{}, error) { + return io.ReadFileContent(filePath) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return "", err + } + + var ableToCast bool + result, ableToCast = rawResult.(string) + if !ableToCast { + return "", errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} + +// SyncFile switches to the host namespace and syncs the file at the +// specified path. +func SyncFile(filePath string) (err error) { + defer func() { + err = errors.Wrapf(err, "failed to sync file %s", filePath) + }() + + fn := func() (interface{}, error) { + return nil, io.SyncFile(filePath) + } + + _, err = RunFunc(fn, 0) + return err +} + +// WriteFile switches to the host namespace and writes the data to the file +// at the specified path. +func WriteFile(filePath, data string) error { + var err error + defer func() { + err = errors.Wrapf(err, "failed to write file %s", filePath) + }() + + fn := func() (interface{}, error) { + return "", os.WriteFile(filePath, []byte(data), 0644) + } + + _, err = RunFunc(fn, 0) + return err +} + +// DeletePath switches to the host namespace and removes the file or +// directory at the specified path. +func DeletePath(path string) error { + var err error + defer func() { + err = errors.Wrapf(err, "failed to delete path %s", path) + }() + + fn := func() (interface{}, error) { + return "", os.RemoveAll(path) + } + + _, err = RunFunc(fn, 0) + return err +} + +// GetDiskStat switches to the host namespace and returns the disk stat +// of the disk at the specified path. +func GetDiskStat(path string) (*types.DiskStat, error) { + var err error + defer func() { + err = errors.Wrapf(err, "failed to get disk stat %s", path) + }() + + fn := func() (interface{}, error) { + return io.GetDiskStat(path) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return nil, err + } + + var ableToCast bool + result, ableToCast := rawResult.(types.DiskStat) + if !ableToCast { + return nil, errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return &result, nil +} diff --git a/vendor/github.com/longhorn/go-common-libs/ns/filelock.go b/vendor/github.com/longhorn/go-common-libs/ns/filelock.go new file mode 100644 index 0000000000..b0ce92c602 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/ns/filelock.go @@ -0,0 +1,143 @@ +package ns + +import ( + "context" + "os" + "sync" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + csync "github.com/longhorn/go-common-libs/sync" + "github.com/longhorn/go-common-libs/types" +) + +// LockFile switches to the host namespace and locks a file at the specified path. +// It returns the file handle. +func LockFile(path string) (result *os.File, err error) { + defer func() { + err = errors.Wrapf(err, "failed to lock file %s", path) + }() + + fn := func() (interface{}, error) { + return csync.LockFile(path) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return nil, err + } + + var ableToCast bool + result, ableToCast = rawResult.(*os.File) + if !ableToCast { + return nil, errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} + +// FileLock is a struct responsible for locking a file. +type FileLock struct { + FilePath string // The path of the file to lock. + File *os.File // The file handle acquired after successful lock. + Timeout time.Duration // The maximum time to wait for lock acquisition. + + done chan struct{} // A channel for signaling lock release. + mutex *sync.Mutex // Mutex to prevent concurrent access to the file handle. +} + +// NewLock creates a new FileLock instance. +func NewLock(filepath string, timeout time.Duration) *FileLock { + if timeout == 0 { + timeout = types.FileLockDefaultTimeout + } + + return &FileLock{ + FilePath: filepath, + Timeout: timeout, + done: make(chan struct{}), + mutex: &sync.Mutex{}, + } +} + +// Lock locks a file. It starts a goroutine to lock the file and returns the file +// handle. If the lock acquisition exceeds the specified timeout, the function +// unlocks the file and returns an error. +// It also starts another goroutine to wait for lock to release and unlock the file. +func (lock *FileLock) Lock() error { + var err error + defer func() { + err = errors.Wrapf(err, "failed to lock file %s", lock.FilePath) + }() + + log := logrus.WithField("file", lock.FilePath) + + // Use a buffered channel for error handling to prevent goroutine leak. + errCh := make(chan error, 1) + + // Use a buffered channel for signaling successful lock acquisition. + resultCh := make(chan struct{}, 1) + + // Use a context with timeout for handling the lock timeout. + ctx, cancel := context.WithTimeout(context.Background(), lock.Timeout) + defer cancel() + + go func() { + lock.mutex.Lock() + defer lock.mutex.Unlock() + + result, err := LockFile(lock.FilePath) + if err != nil { + errCh <- err + return + } + + lock.File = result + resultCh <- struct{}{} + }() + + select { + case <-resultCh: + log.Trace("Locked file") + case <-ctx.Done(): + log.Trace("Timeout waiting for file to lock") + + lock.mutex.Lock() + defer lock.mutex.Unlock() + + if lock.File != nil { + err := csync.UnlockFile(lock.File) + if err != nil { + return errors.Wrapf(err, "failed to unlock timed out lock file %v", lock.FilePath) + } + lock.File = nil + } + + return errors.Errorf("timed out waiting for file to lock %v", lock.FilePath) + } + + // Wait for unlock + go func() { + <-lock.done + log.Trace("Received done signal to unlock file") + + lock.mutex.Lock() + defer lock.mutex.Unlock() + + if lock.File != nil { + err := csync.UnlockFile(lock.File) + if err != nil { + logrus.WithError(err).Error("Failed to gracefully unlock file") + } + lock.File = nil + + } + }() + return nil +} + +// Unlock closes the done channel to signal the lock to release. +func (lock *FileLock) Unlock() { + close(lock.done) +} diff --git a/vendor/github.com/longhorn/go-common-libs/ns/joiner.go b/vendor/github.com/longhorn/go-common-libs/ns/joiner.go new file mode 100644 index 0000000000..203e7504ef --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/ns/joiner.go @@ -0,0 +1,379 @@ +package ns + +import ( + "context" + "fmt" + "os" + "path/filepath" + "runtime" + "sync" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" + + "github.com/longhorn/go-common-libs/proc" + "github.com/longhorn/go-common-libs/types" + "github.com/longhorn/go-common-libs/utils" +) + +type Joiners []*Joiner + +// Joiner is a context with information about a namespace. +type Joiner struct { + namespace types.Namespace // The namespace to join (e.g. net, mnt) + fd int // The file descriptor of the namespace. + flags uintptr // The flags to use when joining the namespace. + + isJoined bool // A boolean to indicate if the namespace has been joined. +} + +// ReverseOrder returns a reversed copy of the Joiners. +func (joiners *Joiners) ReverseOrder() Joiners { + joinerCount := len(*joiners) + + reversed := make(Joiners, joinerCount) + for i, j := joinerCount-1, 0; i >= 0; i, j = i-1, j+1 { + reversed[j] = (*joiners)[i] + } + return reversed +} + +// JoinReverse joins all the namespaces in the Joiners in reverse order. +func (joiners *Joiners) JoinReverse() (err error) { + *joiners = joiners.ReverseOrder() + return joiners.Join() +} + +// Join joins all the namespaces in the Joiners. +func (joiners *Joiners) Join() (err error) { + for _, joiner := range *joiners { + if joiner.isJoined { + logrus.Tracef("Already joined namespace: %s", joiner.namespace) + continue + } + + if joiner.namespace == types.NamespaceMnt { + err := unix.Unshare(unix.CLONE_NEWNS) + if err != nil { + return errors.Wrapf(err, "failed to unshare namespace: %+s", joiner.namespace) + } + } + + if err := unix.Setns(joiner.fd, 0); err != nil { + return errors.Wrapf(err, "failed to set namespace: %+s", joiner.namespace) + } + + joiner.isJoined = true + logrus.Tracef("Joined namespace: %v", joiner.namespace) + } + return nil +} + +// Reset resets all the Joiners. +func (joiners *Joiners) Reset() (err error) { + for _, joiner := range *joiners { + logrus.Tracef("Resetting namespace: %+v", joiner) + joiner = &Joiner{} + } + return nil +} + +// OpenFile opens a file in the Joiners. +func (joiners *Joiners) OpenFile(path string) (fd int, err error) { + return unix.Open(path, unix.O_RDONLY|unix.O_CLOEXEC, 0) +} + +// CloseFiles closes all the files in the Joiners. +func (joiners *Joiners) CloseFiles() { + for _, joiner := range *joiners { + if joiner.fd == -1 { + continue + } + + if err := unix.Close(joiner.fd); err != nil { + logrus.WithError(err).Warnf("Failed to close %v namespace file", joiner.namespace) + continue + } + + joiner.fd = -1 + } +} + +// JoinerDescriptor is a struct that holds information about the namespaces to join. +type JoinerDescriptor struct { + namespaces []types.Namespace // List of namespaces to be joined. + + directory string // The target directory where the namespace files are located. + pid uint64 // Process ID associated with the Joiner. + + origin Joiners // Contexts of the original namespaces. + target Joiners // Contexts of the namespaces to be joined. + + stop chan struct{} // Channel to signal stopping the execution of the function within namespaces. + timeout time.Duration // Timeout duration for the execution of the function within namespaces. +} + +// RunFunc runs the given function in the host namespace. +// Returns the result of the function and any error that occurred. +func RunFunc(fn func() (interface{}, error), timeout time.Duration) (interface{}, error) { + joiner, err := NewJoiner(types.HostProcDirectory, 0) + if err != nil { + return nil, err + } + + return joiner.Run(fn) +} + +type JoinerInterface interface { + Revert() error + Run(fn func() (interface{}, error)) (interface{}, error) +} + +type NewJoinerFunc func(string, time.Duration) (JoinerInterface, error) + +// NewJoiner is a variable holding the function responsible for creating +// a new JoinerInterface. +// By using a variable for the creation function, it allows for easier unit testing +// by substituting a mock implementation. +var NewJoiner NewJoinerFunc = newJoiner + +// newJoiner creates a new JoinerInterface. +func newJoiner(procDirectory string, timeout time.Duration) (nsjoin JoinerInterface, err error) { + log := logrus.WithFields(logrus.Fields{ + "procDirectory": procDirectory, + "timeout": timeout, + }) + log.Trace("Initializing new namespace joiner") + + if timeout == 0 { + timeout = types.NsJoinerDefaultTimeout + } + + if procDirectory == "" { + return &JoinerDescriptor{ + stop: make(chan struct{}), + timeout: timeout, + }, nil + } + + nsDir := proc.GetHostNamespaceDirectory(procDirectory) + procPid := proc.GetHostNamespacePID(procDirectory) + + return &JoinerDescriptor{ + directory: nsDir, + pid: procPid, + + namespaces: []types.Namespace{ + types.NamespaceMnt, + types.NamespaceNet, + }, + + origin: Joiners{}, + target: Joiners{}, + + stop: make(chan struct{}), + timeout: timeout, + }, err +} + +// OpenNamespaceFiles opens required namespace files. +func (jd *JoinerDescriptor) OpenNamespaceFiles() (err error) { + defer func() { + err = errors.Wrapf(err, "failed to open namespace files") + if err != nil { + _ = jd.Revert() + } + }() + + for _, namespace := range jd.namespaces { + err = jd.openAndRecordNamespaceFiles(namespace) + if err != nil { + break + } + } + return err +} + +// openAndRecordNamespaceFiles opens and records current and target namespace files. +func (jd *JoinerDescriptor) openAndRecordNamespaceFiles(namespace types.Namespace) error { + logrus.Tracef("Opening %s namespace file", namespace) + + ns := namespace.String() + + if err := jd.openAndRecordOriginalNamespaceFile(ns, namespace); err != nil { + return err + } + + return jd.openAndRecordTargetNamespaceFile(ns, namespace) +} + +// openAndRecordOriginalNamespaceFile opens the original namespace file and records +// the file descriptor and namespace information. +// The original namespace file is the namespace file of the process thread that is +// executing the joiner (e.g. /proc/1/task/2/ns/mnt) +func (jd *JoinerDescriptor) openAndRecordOriginalNamespaceFile(ns string, namespace types.Namespace) error { + pthreadFile := filepath.Join("/proc", fmt.Sprint(os.Getpid()), "task", fmt.Sprint(unix.Gettid()), "ns", ns) + originFd, err := jd.origin.OpenFile(pthreadFile) + if err != nil { + return errors.Wrapf(err, "failed to open process thread file %v", pthreadFile) + } + jd.origin = append(jd.origin, &Joiner{ + namespace: namespace, + fd: originFd, + flags: namespace.Flag(), + }) + return nil +} + +// openAndRecordTargetNamespaceFile opens the target namespace file and records +// the file descriptor and namespace information. +// The target namespace file is the namespace file of the process that is being +// joined (e.g. /host/proc/123/ns/mnt) +func (jd *JoinerDescriptor) openAndRecordTargetNamespaceFile(ns string, namespace types.Namespace) error { + namespaceFile := filepath.Join(jd.directory, ns) + targetFd, err := jd.target.OpenFile(namespaceFile) + if err != nil { + return errors.Wrapf(err, "failed to open namespace file %v", namespaceFile) + } + jd.target = append(jd.target, &Joiner{ + namespace: namespace, + fd: targetFd, + flags: namespace.Flag(), + }) + return nil +} + +// Join joins the target namespaces. +func (jd *JoinerDescriptor) Join() (err error) { + defer func() { + err = errors.Wrap(err, "failed to join namespaces") + }() + return jd.target.Join() +} + +// Revert reverts to the original namespaces. +func (jd *JoinerDescriptor) Revert() (err error) { + if jd.target == nil { + return nil + } + + defer func() { + err = errors.Wrap(err, "failed to revert namespaces") + if err == nil { + logrus.Tracef("Reverted to %v namespace", jd.directory) + } + + jd.target.CloseFiles() + _ = jd.target.Reset() + + jd.origin.CloseFiles() + _ = jd.origin.Reset() + }() + + logrus.Trace("Reverting namespaces") + if err := jd.origin.JoinReverse(); err != nil { + return err + } + + _, err = os.Stat(jd.directory) + return err +} + +// Run executes the function in the target namespace. +// The function is executed in a goroutine with a locked OS thread to ensure +// namespace isolation. +func (jd *JoinerDescriptor) Run(fn func() (interface{}, error)) (interface{}, error) { + errCh := make(chan error) + resultCh := make(chan interface{}) + + _, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Use a wait group to wait for the goroutine to finish + var wg sync.WaitGroup + wg.Add(1) + + // Goroutine to run the function in the target namespace. + go func() { + defer wg.Done() + + defer close(errCh) + defer close(resultCh) + defer cancel() + + // The goroutine runs with a locked OS thread to ensure namespace isolation. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + // Open the namespace files and revert them after execution. + err := jd.OpenNamespaceFiles() + if err != nil { + errCh <- err + return + } + defer func() { + _ = jd.Revert() + }() + + // Join the target namespaces. + logrus.Trace("Joining target namespaces") + err = jd.Join() + if err != nil { + errCh <- err + return + } + + // Execute the given function and send the result or error to the channels. + select { + case <-jd.stop: + return // The stop signal was received, exit without running the function. + default: + output, err := fn() + if err != nil { + errCh <- err + return + } + + resultCh <- output + } + }() + + // Goroutine to wait for the function to finish and stop the joiner. + var stopOnce sync.Once + go func() { + wg.Wait() + + // Stop the joiner once to avoid race conditions. + stopOnce.Do(func() { + close(jd.stop) + }) + }() + + // Get the function name for logging. + fnName := utils.GetFunctionName(fn) + + select { + case err := <-errCh: + return nil, errors.Wrapf(err, types.ErrNamespaceFuncFmt, fnName) + + case result := <-resultCh: + logrus.Tracef("Completed function %v in namespace: %+v", fnName, result) + return result, nil + + case <-jd.stop: + logrus.Tracef("Received stop signal while running function: %v", fnName) + stopOnce.Do(func() { + close(jd.stop) + }) + return nil, nil + + case <-time.After(jd.timeout): + // The function execution timed out, clean up and return an error. + stopOnce.Do(func() { + close(jd.stop) + }) + return nil, errors.Errorf("timeout running function: %v", fnName) + } +} diff --git a/vendor/github.com/longhorn/go-common-libs/ns/misc.go b/vendor/github.com/longhorn/go-common-libs/ns/misc.go new file mode 100644 index 0000000000..c590abe800 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/ns/misc.go @@ -0,0 +1,23 @@ +package ns + +import ( + "github.com/sirupsen/logrus" + + "github.com/longhorn/go-common-libs/types" +) + +// GetDefaultProcessName returns the default process name for namespace switching based on the OS distro. +func GetDefaultProcessName() string { + osDistro, err := GetOSDistro() + if err != nil { + logrus.Trace("failed to get os distro, fallback to default host process") + return types.ProcessNone + } + + switch osDistro { + case types.OSDistroTalosLinux: + return types.ProcessKubelet + default: + return types.ProcessNone + } +} diff --git a/vendor/github.com/longhorn/go-common-libs/ns/sys.go b/vendor/github.com/longhorn/go-common-libs/ns/sys.go new file mode 100644 index 0000000000..ff8b561687 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/ns/sys.go @@ -0,0 +1,99 @@ +package ns + +import ( + "syscall" + + "github.com/pkg/errors" + + "github.com/longhorn/go-common-libs/io" + "github.com/longhorn/go-common-libs/sys" + "github.com/longhorn/go-common-libs/types" +) + +// GetKernelRelease switches to the host namespace and retrieves the kernel release. +func GetKernelRelease() (string, error) { + var err error + defer func() { + err = errors.Wrap(err, "failed to get kernel release") + }() + + fn := func() (interface{}, error) { + return sys.GetKernelRelease() + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return "", err + } + + var result string + var ableToCast bool + result, ableToCast = rawResult.(string) + if !ableToCast { + return "", errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} + +// GetOSDistro switches to the host namespace and retrieves the OS distro. +func GetOSDistro() (result string, err error) { + defer func() { + err = errors.Wrapf(err, "failed to get host OS distro") + }() + + fn := func() (interface{}, error) { + return io.ReadFileContent(types.OsReleaseFilePath) + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return "", err + } + + var ableToCast bool + result, ableToCast = rawResult.(string) + if !ableToCast { + return "", errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + + return sys.GetOSDistro(result) +} + +// Sync switches to the host namespace and calls sync. +func Sync() (err error) { + defer func() { + err = errors.Wrap(err, "failed to get kernel release") + }() + + fn := func() (interface{}, error) { + syscall.Sync() + return nil, nil + } + + _, err = RunFunc(fn, 0) + return err +} + +// GetSystemBlockDevices switches to the host namespace and retrieves the +// system block devices. +func GetSystemBlockDevices() (result map[string]types.BlockDeviceInfo, err error) { + defer func() { + err = errors.Wrapf(err, "failed to get system block devices") + }() + + fn := func() (interface{}, error) { + return sys.GetSystemBlockDeviceInfo() + } + + rawResult, err := RunFunc(fn, 0) + if err != nil { + return nil, err + } + + var ableToCast bool + result, ableToCast = rawResult.(map[string]types.BlockDeviceInfo) + if !ableToCast { + return nil, errors.Errorf(types.ErrNamespaceCastResultFmt, result, rawResult) + } + return result, nil +} diff --git a/vendor/github.com/longhorn/go-common-libs/proc/proc.go b/vendor/github.com/longhorn/go-common-libs/proc/proc.go new file mode 100644 index 0000000000..581b7ec5e4 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/proc/proc.go @@ -0,0 +1,210 @@ +package proc + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/c9s/goprocinfo/linux" + "github.com/mitchellh/go-ps" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + "github.com/longhorn/go-common-libs/types" +) + +// ProcessFinder is a struct to find process information. +type ProcessFinder struct { + procDirectory string // The directory path where the process information is stored. +} + +func NewProcFinder(procDir string) *ProcessFinder { + return &ProcessFinder{procDir} +} + +// GetProcessStatus returns the process status for the given process. +func (p *ProcessFinder) GetProcessStatus(proc string) (*linux.ProcessStatus, error) { + path := filepath.Join(p.procDirectory, proc, "status") + return linux.ReadProcessStatus(path) +} + +// FindAncestorByName returns the ancestor process status for the given process. +func (p *ProcessFinder) FindAncestorByName(ancestorProcess, pid string) (*linux.ProcessStatus, error) { + ps, err := p.GetProcessStatus(pid) + if err != nil { + return nil, err + } + + for { + if ps.Name == ancestorProcess { + return ps, nil + } + + if ps.PPid == 0 { + break + } + + ps, err = p.GetProcessStatus(fmt.Sprint(ps.PPid)) + if err != nil { + return nil, err + } + } + + return nil, errors.Errorf("failed to find the ancestor process for %v", ancestorProcess) +} + +// GetProcessPIDs returns the PIDs for the given process name. +func GetProcessPIDs(processName, procDir string) ([]uint64, error) { + files, err := os.ReadDir(procDir) + if err != nil { + return nil, err + } + + processFinder := NewProcFinder(procDir) + + var pids []uint64 + for _, file := range files { + if !file.IsDir() { + continue + } + + if _, err := strconv.Atoi(file.Name()); err != nil { + // Not a numerical values representing a running process + continue + } + + pid, err := strconv.ParseUint(file.Name(), 10, 64) + if err != nil { + // Not a numerical values representing a running process + continue + } + + processStatus, err := processFinder.GetProcessStatus(file.Name()) + if err != nil { + logrus.WithError(err).Debugf("Failed to get PID (%v) status", pid) + continue + } + + // The "Name" field of the process status is set to the filename of the executable. + // Within the proc directory structure, processes are organized by + // their PIDs. This means that multiple processes running with the same executable + // name can coexist. + if processStatus.Name == processName { + pids = append(pids, pid) + } + } + + // If no process is found, return the host namespace PID + if len(pids) == 0 { + pids = append(pids, GetHostNamespacePID(types.HostProcDirectory)) + } + + logrus.Tracef("Found PIDs (%v) for process %v", pids, processName) + return pids, nil +} + +// GetHostNamespacePID returns the PID of the host namespace. +func GetHostNamespacePID(hostProcDir string) uint64 { + pf := NewProcFinder(hostProcDir) + processes := []string{ + types.ProcessDockerd, + types.ProcessContainerd, + types.ProcessContainerdShim, + } + for _, process := range processes { + proc, err := pf.FindAncestorByName(process, types.ProcessSelf) + if err != nil { + continue + } + return proc.Pid + + } + // fall back to use pid 1 + return 1 +} + +// GetNamespaceDirectory returns the namespace directory for the given PID. +func GetNamespaceDirectory(procDir, pid string) string { + return filepath.Join(procDir, pid, "ns") +} + +// GetHostNamespaceDirectory returns the namespace directory for the host namespace. +func GetHostNamespaceDirectory(hostProcDir string) string { + return GetNamespaceDirectory(hostProcDir, fmt.Sprint(GetHostNamespacePID(hostProcDir))) +} + +// GetProcessAncestorNamespaceDirectory returns the namespace directory for the +// ancestor of the given process. +func GetProcessAncestorNamespaceDirectory(process, procDir string) (string, error) { + pf := NewProcFinder(procDir) + proc, err := pf.FindAncestorByName(process, types.ProcessSelf) + if err != nil { + return "", errors.Errorf("failed to get ancestor namespace of %v", process) + } + return GetNamespaceDirectory(procDir, fmt.Sprint(proc.Pid)), nil +} + +// GetProcessNamespaceDirectory returns the namespace directory for the given process. +// If processName is ProcessNone, it returns the host namespace directory. +func GetProcessNamespaceDirectory(processName, procDir string) (string, error) { + if processName == types.ProcessNone { + return GetHostNamespaceDirectory(procDir), nil + } + + pids, err := GetProcessPIDs(processName, procDir) + if err != nil { + return "", err + } + + return GetNamespaceDirectory(procDir, fmt.Sprint(pids[0])), nil +} + +// FindProcessByName finds a process by name and returns the process +func FindProcessByName(name string) (*os.Process, error) { + processes, err := ps.Processes() + if err != nil { + return nil, fmt.Errorf("failed to list processes") + } + + for _, process := range processes { + if process.Executable() == name { + return os.FindProcess(process.Pid()) + } + } + + return nil, fmt.Errorf("process %s is not found", name) +} + +// FindProcessByCmdline finds the processes with matching cmdline +func FindProcessByCmdline(cmdline string) ([]*os.Process, error) { + processes, err := ps.Processes() + if err != nil { + return nil, errors.Wrap(err, "failed to list processes") + } + + var foundProcesses []*os.Process + + for _, process := range processes { + cmdlinePath := filepath.Join("/proc", strconv.Itoa(process.Pid()), "cmdline") + cmdlineContent, err := os.ReadFile(cmdlinePath) + if err != nil { + continue + } + + if strings.HasPrefix(string(cmdlineContent), cmdline) { + process, err := os.FindProcess(process.Pid()) + if err != nil { + return nil, err + } + foundProcesses = append(foundProcesses, process) + } + } + + if len(foundProcesses) == 0 { + return nil, fmt.Errorf("process with cmdline %s is not found", cmdline) + } + + return foundProcesses, nil +} diff --git a/vendor/github.com/longhorn/go-common-libs/sync/filelock.go b/vendor/github.com/longhorn/go-common-libs/sync/filelock.go new file mode 100644 index 0000000000..16eb8f79b1 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/sync/filelock.go @@ -0,0 +1,50 @@ +package sync + +import ( + "os" + "syscall" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +// LockFile is responsible for locking a file and returning a file handle. +func LockFile(filePath string) (file *os.File, err error) { + log := logrus.WithField("file", filePath) + + defer func() { + err = errors.Wrapf(err, "failed to lock file %s", filePath) + if err != nil && file != nil { + e := file.Close() + if e != nil { + err = errors.Wrapf(err, "failed to close file: %v", e) + } + } + }() + + log.Trace("Locking file") + + file, err = os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return nil, err + } + + return file, syscall.Flock(int(file.Fd()), syscall.LOCK_EX) +} + +// UnlockFile is responsible for unlocking a file and closing the file handle. +func UnlockFile(file *os.File) (err error) { + defer func() { + err = errors.Wrapf(err, "failed to unlock file %s", file.Name()) + }() + + log := logrus.WithField("file", file.Name()) + + err = syscall.Flock(int(file.Fd()), syscall.LOCK_UN) + if err != nil { + log.WithError(err).Warn("Failed to unlock file") + } + + log.Trace("Unlocked file") + return file.Close() +} diff --git a/vendor/github.com/longhorn/go-common-libs/sys/sys.go b/vendor/github.com/longhorn/go-common-libs/sys/sys.go new file mode 100644 index 0000000000..e4e23a30b2 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/sys/sys.go @@ -0,0 +1,129 @@ +package sys + +import ( + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + "syscall" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + "github.com/longhorn/go-common-libs/types" +) + +// GetKernelRelease returns the kernel release string. +func GetKernelRelease() (string, error) { + utsname := &syscall.Utsname{} + if err := syscall.Uname(utsname); err != nil { + logrus.WithError(err).Warn("Failed to get kernel release") + return "", err + } + + // Extract the kernel release from the Utsname structure + release := make([]byte, 0, len(utsname.Release)) + for _, b := range utsname.Release { + if b == 0x00 { + logrus.Trace("Found end of kernel release string [0x00]") + break + } + release = append(release, byte(b)) + } + return string(release), nil +} + +// GetOSDistro reads the /etc/os-release file and returns the ID field. +func GetOSDistro(osReleaseContent string) (string, error) { + var err error + defer func() { + err = errors.Wrapf(err, "failed to get host OS distro") + }() + + lines := strings.Split(osReleaseContent, "\n") + for _, line := range lines { + if strings.HasPrefix(line, "ID=") { + id := strings.TrimPrefix(line, "ID=") + id = strings.Trim(id, `"`) + logrus.Tracef("Found OS distro: %v", id) + return id, nil + } + } + + return "", errors.Errorf("failed to find ID field in %v", types.OsReleaseFilePath) +} + +// GetSystemBlockDeviceInfo returns the block device info for the system. +func GetSystemBlockDeviceInfo() (map[string]types.BlockDeviceInfo, error) { + return getSystemBlockDeviceInfo(types.SysClassBlockDirectory, os.ReadDir, os.ReadFile) +} + +// getSystemBlockDeviceInfo returns the block device info for the system. +// It injects the readDirFn and readFileFn for testing. +func getSystemBlockDeviceInfo(sysClassBlockDirectory string, readDirFn func(string) ([]os.DirEntry, error), readFileFn func(string) ([]byte, error)) (map[string]types.BlockDeviceInfo, error) { + devices, err := readDirFn(sysClassBlockDirectory) + if err != nil { + return nil, err + } + + readDeviceNumber := func(numbers []string, index int) (int64, error) { + if len(numbers) <= index { + return 0, errors.Errorf("invalid file format") + } + + number, err := strconv.ParseInt(numbers[index], 10, 64) + if err != nil { + return 0, err + } + return number, nil + } + + deviceInfo := make(map[string]types.BlockDeviceInfo, len(devices)) + for _, device := range devices { + deviceName := device.Name() + devicePath := filepath.Join(sysClassBlockDirectory, deviceName, "dev") + + if _, err := os.Stat(devicePath); os.IsNotExist(err) { + // If the device path does not exist, check if the device path exists in the "device" directory. + // Some devices such as "nvme0cn1" created from SPDK do not have "dev" file under their sys/class/block directory. + alternativeDevicePath := filepath.Join(sysClassBlockDirectory, deviceName, "device", "dev") + if _, altErr := os.Stat(alternativeDevicePath); os.IsNotExist(altErr) { + errs := fmt.Errorf("primary error: %w; alternative error: %w", err, altErr) + logrus.WithFields(logrus.Fields{ + "device": deviceName, + "primaryPath": devicePath, + "alternativePath": alternativeDevicePath, + }).WithError(errs).Debugf("failed to find dev file in either primary or alternative path") + continue + } + + devicePath = alternativeDevicePath + } + + data, err := readFileFn(devicePath) + if err != nil { + return nil, err + } + + numbers := strings.Split(strings.TrimSpace(string(data)), ":") + major, err := readDeviceNumber(numbers, 0) + if err != nil { + logrus.WithError(err).Warnf("failed to read device %s major", deviceName) + continue + } + + minor, err := readDeviceNumber(numbers, 1) + if err != nil { + logrus.WithError(err).Warnf("failed to read device %s minor", deviceName) + continue + } + + deviceInfo[deviceName] = types.BlockDeviceInfo{ + Name: deviceName, + Major: int(major), + Minor: int(minor), + } + } + return deviceInfo, nil +} diff --git a/vendor/github.com/longhorn/go-common-libs/test/fake/file.go b/vendor/github.com/longhorn/go-common-libs/test/fake/file.go new file mode 100644 index 0000000000..d7c350f7ba --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/test/fake/file.go @@ -0,0 +1,36 @@ +package fake + +import ( + "os" + "path/filepath" + + "gopkg.in/check.v1" +) + +func CreateTempDirectory(parentDirectory string, c *check.C) string { + if parentDirectory != "" { + _, err := os.Stat(parentDirectory) + c.Assert(err, check.IsNil) + } + + tempDir, err := os.MkdirTemp(parentDirectory, "test-") + c.Assert(err, check.IsNil) + return tempDir +} + +func CreateTempFile(directory, fileName, content string, c *check.C) *os.File { + var err error + var tempFile *os.File + if fileName != "" { + tempFile, err = os.Create(filepath.Join(directory, fileName)) + c.Assert(err, check.IsNil) + } else { + tempFile, err = os.CreateTemp(directory, "test-") + c.Assert(err, check.IsNil) + } + + _, err = tempFile.WriteString(content) + c.Assert(err, check.IsNil) + + return tempFile +} diff --git a/vendor/github.com/longhorn/go-common-libs/test/fake/namespace.go b/vendor/github.com/longhorn/go-common-libs/test/fake/namespace.go new file mode 100644 index 0000000000..98c1bc3207 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/test/fake/namespace.go @@ -0,0 +1,42 @@ +package fake + +import ( + "time" +) + +type Executor struct{} + +func (nsexec *Executor) Execute([]string, string, []string, time.Duration) (string, error) { + return "output", nil +} + +func (nsexec *Executor) ExecuteWithTimeout([]string, string, []string, time.Duration) (string, error) { + return "output", nil +} + +func (nsexec *Executor) ExecuteWithoutTimeout([]string, string, []string, time.Duration) (string, error) { + return "output", nil +} + +func (nsexec *Executor) ExecuteWithStdin(string, []string, string, time.Duration) (string, error) { + return "output", nil +} + +func (nsexec *Executor) ExecuteWithStdinPipe(string, []string, string, time.Duration) (string, error) { + return "output", nil +} + +type Joiner struct { + MockDelay time.Duration + MockResult interface{} + MockError error +} + +func (nsjoin *Joiner) Run(fn func() (interface{}, error)) (interface{}, error) { + time.Sleep(nsjoin.MockDelay) + return nsjoin.MockResult, nsjoin.MockError +} + +func (nsjoin *Joiner) Revert() error { + return nil +} diff --git a/vendor/github.com/longhorn/go-common-libs/test/fake/system.go b/vendor/github.com/longhorn/go-common-libs/test/fake/system.go new file mode 100644 index 0000000000..39613a7028 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/test/fake/system.go @@ -0,0 +1,45 @@ +package fake + +import ( + "fmt" + "io/fs" + "strings" +) + +// FileSystem is a mock implementation of the fs.FS interface +type FileSystem struct { + DirEntries []fs.DirEntry + Data []byte +} + +func (fs *FileSystem) ReadDir(string) ([]fs.DirEntry, error) { + return fs.DirEntries, nil +} + +func (fs *FileSystem) ReadFile(filePath string) ([]byte, error) { + if fs.Data != nil { + return fs.Data, nil + } + + for i, dirEntry := range fs.DirEntries { + if strings.Contains(filePath, dirEntry.Name()) { + return []byte(fmt.Sprintf("8:%d\n", i)), nil + } + } + + return nil, nil +} + +func DirEntry(name string, isDir bool) fs.DirEntry { + return &mockFile{name: name, isDir: isDir} +} + +type mockFile struct { + name string + isDir bool +} + +func (m *mockFile) Name() string { return m.name } +func (m *mockFile) IsDir() bool { return m.isDir } +func (m *mockFile) Type() fs.FileMode { return 0 } +func (m *mockFile) Info() (fs.FileInfo, error) { return nil, nil } diff --git a/vendor/github.com/longhorn/go-common-libs/types/crypto.go b/vendor/github.com/longhorn/go-common-libs/types/crypto.go new file mode 100644 index 0000000000..9cde14da09 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/types/crypto.go @@ -0,0 +1,7 @@ +package types + +import ( + "time" +) + +const LuksTimeout = time.Minute diff --git a/vendor/github.com/longhorn/go-common-libs/types/exec.go b/vendor/github.com/longhorn/go-common-libs/types/exec.go new file mode 100644 index 0000000000..93d1652db8 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/types/exec.go @@ -0,0 +1,15 @@ +package types + +import ( + "time" +) + +const ( + BinaryCryptsetup = "cryptsetup" + BinaryFstrim = "fstrim" +) + +const ( + ExecuteNoTimeout = time.Duration(-1) + ExecuteDefaultTimeout = time.Minute +) diff --git a/vendor/github.com/longhorn/go-common-libs/types/file.go b/vendor/github.com/longhorn/go-common-libs/types/file.go new file mode 100644 index 0000000000..e67b01dd74 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/types/file.go @@ -0,0 +1,33 @@ +package types + +import ( + "time" +) + +var FileLockDefaultTimeout = 24 * time.Hour + +type DiskDriver string + +const ( + DiskDriverNone = DiskDriver("") + DiskDriverAuto = DiskDriver("auto") + DiskDriverAio = DiskDriver("aio") + DiskDriverNvme = DiskDriver("nvme") + DiskDriverVirtioScsi = DiskDriver("virtio-scsi") + DiskDriverVirtioBlk = DiskDriver("virtio-blk") + DiskDriverVirtioPci = DiskDriver("virtio-pci") + DiskDriverUioPciGeneric = DiskDriver("uio_pci_generic") +) + +type DiskStat struct { + DiskID string + Name string + Path string + Type string + Driver DiskDriver + FreeBlocks int64 + TotalBlocks int64 + BlockSize int64 + StorageMaximum int64 + StorageAvailable int64 +} diff --git a/vendor/github.com/longhorn/go-common-libs/types/misc.go b/vendor/github.com/longhorn/go-common-libs/types/misc.go new file mode 100644 index 0000000000..083d53bde3 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/types/misc.go @@ -0,0 +1,3 @@ +package types + +const RandomIDDefaultLength = 8 diff --git a/vendor/github.com/longhorn/go-common-libs/types/namespace.go b/vendor/github.com/longhorn/go-common-libs/types/namespace.go new file mode 100644 index 0000000000..7358a4076c --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/types/namespace.go @@ -0,0 +1,42 @@ +package types + +import ( + "time" + + "golang.org/x/sys/unix" +) + +const ( + HostProcDirectory = "/host/proc" + ProcDirectory = "/proc" +) + +const NsBinary = "nsenter" + +const ( + ErrNamespaceCastResultFmt = "failed casting result to %T: %v" + ErrNamespaceFuncFmt = "failed function: %v" +) + +var NsJoinerDefaultTimeout = 24 * time.Hour + +type Namespace string + +const ( + NamespaceIpc = Namespace("ipc") + NamespaceMnt = Namespace("mnt") + NamespaceNet = Namespace("net") +) + +func (ns Namespace) Flag() uintptr { + switch ns { + case NamespaceNet: + return unix.CLONE_NEWNET + default: + return 0 + } +} + +func (ns Namespace) String() string { + return string(ns) +} diff --git a/vendor/github.com/longhorn/go-common-libs/types/proc.go b/vendor/github.com/longhorn/go-common-libs/types/proc.go new file mode 100644 index 0000000000..27aaa0a90c --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/types/proc.go @@ -0,0 +1,12 @@ +package types + +const ( + ProcessContainerd = "containerd" + ProcessContainerdShim = "containerd-shim" + ProcessDockerd = "dockerd" + ProcessNone = "" + ProcessSelf = "self" + + // ProcessKubelet is not a standard process name for Kubelet, used by Talos Linux only. + ProcessKubelet = "kubelet" +) diff --git a/vendor/github.com/longhorn/go-common-libs/types/sys.go b/vendor/github.com/longhorn/go-common-libs/types/sys.go new file mode 100644 index 0000000000..15155b3b2c --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/types/sys.go @@ -0,0 +1,13 @@ +package types + +const OsReleaseFilePath = "/etc/os-release" +const SysClassBlockDirectory = "/sys/class/block/" + +const OSDistroTalosLinux = "talos" + +// BlockDeviceInfo is a struct that contains the block device info. +type BlockDeviceInfo struct { + Name string // Name of the block device (e.g. sda, sdb, sdc, etc.). + Major int // Major number of the block device. + Minor int // Minor number of the block device. +} diff --git a/vendor/github.com/longhorn/go-common-libs/utils/grpc.go b/vendor/github.com/longhorn/go-common-libs/utils/grpc.go new file mode 100644 index 0000000000..237a6ec481 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/utils/grpc.go @@ -0,0 +1,17 @@ +package utils + +import ( + "strings" + "time" +) + +const ( + GRPCServiceTimeout = 3 * time.Minute +) + +func GetGRPCAddress(address string) string { + address = strings.TrimPrefix(address, "tcp://") + address = strings.TrimPrefix(address, "http://") + + return address +} diff --git a/vendor/github.com/longhorn/go-common-libs/utils/longhorn_naming.go b/vendor/github.com/longhorn/go-common-libs/utils/longhorn_naming.go new file mode 100644 index 0000000000..a25e0ce745 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/utils/longhorn_naming.go @@ -0,0 +1,11 @@ +package utils + +import ( + "regexp" +) + +// IsEngineProcess distinguish if the process is a engine process by its name. +func IsEngineProcess(processName string) bool { + // engine process name example: pvc-5a8ee916-5989-46c6-bafc-ddbf7c802499-e-0 + return regexp.MustCompile(`.+?-e-.*\d$`).MatchString(processName) +} diff --git a/vendor/github.com/longhorn/go-common-libs/utils/misc.go b/vendor/github.com/longhorn/go-common-libs/utils/misc.go new file mode 100644 index 0000000000..8eeb4177b4 --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/utils/misc.go @@ -0,0 +1,100 @@ +package utils + +import ( + "crypto/rand" + "math/big" + "path/filepath" + "reflect" + "runtime" + + "github.com/google/uuid" + "github.com/pkg/errors" + + "github.com/longhorn/go-common-libs/types" +) + +// Contains checks if the given slice contains the given value. +func Contains[T comparable](slice []T, value T) bool { + for _, s := range slice { + if s == value { + return true + } + } + return false +} + +// GetFunctionName returns the . of the given function. +func GetFunctionName(f interface{}) string { + value := reflect.ValueOf(f) + if value.Kind() != reflect.Func { + return "" + } + return filepath.Base(runtime.FuncForPC(value.Pointer()).Name()) +} + +// GetFunctionPath returns the full path of the given function. +func GetFunctionPath(f interface{}) string { + getFn := func() string { + return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name() + } + return GetFunctionInfo(f, getFn) +} + +// GetFunctionInfo take a function as interface{} and a function for getting the info. +func GetFunctionInfo(f interface{}, getInfoFn func() string) string { + value := reflect.ValueOf(f) + if value.Kind() != reflect.Func { + return "" + } + return getInfoFn() +} + +// IsStringInSlice checks if the given string 'item' is present in the 'list' of strings. +func IsStringInSlice(list []string, item string) bool { + for _, str := range list { + if str == item { + return true + } + } + return false +} + +// RandomID returns a random string with the specified length. +// If the specified length is less than or equal to 0, the default length will +// be used. +func RandomID(randomIDLenth int) string { + if randomIDLenth <= 0 { + randomIDLenth = types.RandomIDDefaultLength + } + + uuid := UUID() + + if len(uuid) > randomIDLenth { + uuid = uuid[:randomIDLenth] + } + return uuid +} + +// UUID returns a random UUID string. +func UUID() string { + return uuid.New().String() +} + +// GenerateRandomNumber generates a random positive number between lower and upper. +// The return value should be between [lower, upper), and error is nil when success. +// If the error is not nil, the return value is 0. +func GenerateRandomNumber(lower, upper int64) (int64, error) { + if lower > upper { + return 0, errors.Errorf("invalid boundary: [%v, %v)", lower, upper) + } + + if lower == upper { + return lower, nil + } + + randNum, err := rand.Int(rand.Reader, big.NewInt(upper-lower)) + if err != nil { + return 0, err + } + return (lower + randNum.Int64()), nil +} diff --git a/vendor/github.com/longhorn/go-common-libs/utils/mount.go b/vendor/github.com/longhorn/go-common-libs/utils/mount.go new file mode 100644 index 0000000000..f234ae1a3c --- /dev/null +++ b/vendor/github.com/longhorn/go-common-libs/utils/mount.go @@ -0,0 +1,14 @@ +package utils + +import ( + "k8s.io/mount-utils" +) + +func IsMountPointReadOnly(mp mount.MountPoint) bool { + for _, opt := range mp.Opts { + if opt == "ro" { + return true + } + } + return false +} diff --git a/vendor/github.com/longhorn/go-iscsi-helper/iscsi/initiator.go b/vendor/github.com/longhorn/go-iscsi-helper/iscsi/initiator.go index 7834ce86a9..abe4c77b00 100644 --- a/vendor/github.com/longhorn/go-iscsi-helper/iscsi/initiator.go +++ b/vendor/github.com/longhorn/go-iscsi-helper/iscsi/initiator.go @@ -11,7 +11,8 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/longhorn/go-iscsi-helper/util" + lhns "github.com/longhorn/go-common-libs/ns" + lhtypes "github.com/longhorn/go-common-libs/types" ) var ( @@ -29,28 +30,22 @@ const ( scanModeManual = "manual" scanModeAuto = "auto" ScanTimeout = 10 * time.Second - - shellBinary = "sh" ) -func CheckForInitiatorExistence(ne *util.NamespaceExecutor) error { +func CheckForInitiatorExistence(nsexec *lhns.Executor) error { opts := []string{ "--version", } - _, err := ne.Execute(iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } -func UpdateScsiDeviceTimeout(devName string, timeout int64, ne *util.NamespaceExecutor) error { - opts := []string{ - "-c", - fmt.Sprintf("echo %v > /sys/block/%v/device/timeout", timeout, devName), - } - _, err := ne.Execute(shellBinary, opts) - return err +func UpdateScsiDeviceTimeout(devName string, timeout int64, nsexec *lhns.Executor) error { + deviceTimeoutFile := filepath.Join("/sys/block", devName, "device", "timeout") + return lhns.WriteFile(deviceTimeoutFile, fmt.Sprint(timeout)) } -func UpdateIscsiDeviceAbortTimeout(target string, timeout int64, ne *util.NamespaceExecutor) error { +func UpdateIscsiDeviceAbortTimeout(target string, timeout int64, nsexec *lhns.Executor) error { opts := []string{ "-m", "node", "-T", target, @@ -58,17 +53,17 @@ func UpdateIscsiDeviceAbortTimeout(target string, timeout int64, ne *util.Namesp "-n", "node.session.err_timeo.abort_timeout", "-v", strconv.FormatInt(timeout, 10), } - _, err := ne.Execute(iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } -func DiscoverTarget(ip, target string, ne *util.NamespaceExecutor) error { +func DiscoverTarget(ip, target string, nsexec *lhns.Executor) error { opts := []string{ "-m", "discovery", "-t", "sendtargets", "-p", ip, } - output, err := ne.Execute(iscsiBinary, opts) + output, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return err } @@ -87,7 +82,7 @@ func DiscoverTarget(ip, target string, ne *util.NamespaceExecutor) error { return nil } -func DeleteDiscoveredTarget(ip, target string, ne *util.NamespaceExecutor) error { +func DeleteDiscoveredTarget(ip, target string, nsexec *lhns.Executor) error { opts := []string{ "-m", "node", "-o", "delete", @@ -96,11 +91,11 @@ func DeleteDiscoveredTarget(ip, target string, ne *util.NamespaceExecutor) error if ip != "" { opts = append(opts, "-p", ip) } - _, err := ne.Execute(iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } -func IsTargetDiscovered(ip, target string, ne *util.NamespaceExecutor) bool { +func IsTargetDiscovered(ip, target string, nsexec *lhns.Executor) bool { opts := []string{ "-m", "node", "-T", target, @@ -108,30 +103,30 @@ func IsTargetDiscovered(ip, target string, ne *util.NamespaceExecutor) bool { if ip != "" { opts = append(opts, "-p", ip) } - _, err := ne.Execute(iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) return err == nil } -func LoginTarget(ip, target string, ne *util.NamespaceExecutor) error { +func LoginTarget(ip, target string, nsexec *lhns.Executor) error { opts := []string{ "-m", "node", "-T", target, "-p", ip, "--login", } - _, err := ne.Execute(iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return err } - scanMode, err := getIscsiNodeSessionScanMode(ip, target, ne) + scanMode, err := getIscsiNodeSessionScanMode(ip, target, nsexec) if err != nil { return errors.Wrap(err, "Failed to get node.session.scan mode") } if scanMode == scanModeManual { logrus.Infof("Manually rescan LUNs of the target %v:%v", target, ip) - if err := manualScanSession(ip, target, ne); err != nil { + if err := manualScanSession(ip, target, nsexec); err != nil { return errors.Wrapf(err, "failed to manually rescan iscsi session of target %v:%v", target, ip) } } else { @@ -142,7 +137,7 @@ func LoginTarget(ip, target string, ne *util.NamespaceExecutor) error { } // LogoutTarget will logout all sessions if ip == "" -func LogoutTarget(ip, target string, ne *util.NamespaceExecutor) error { +func LogoutTarget(ip, target string, nsexec *lhns.Executor) error { opts := []string{ "-m", "node", "-T", target, @@ -151,16 +146,16 @@ func LogoutTarget(ip, target string, ne *util.NamespaceExecutor) error { if ip != "" { opts = append(opts, "-p", ip) } - _, err := ne.Execute(iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } -func GetDevice(ip, target string, lun int, ne *util.NamespaceExecutor) (*util.KernelDevice, error) { +func GetDevice(ip, target string, lun int, nsexec *lhns.Executor) (*lhtypes.BlockDeviceInfo, error) { var err error - var dev *util.KernelDevice + var dev *lhtypes.BlockDeviceInfo for i := 0; i < DeviceWaitRetryCounts; i++ { - dev, err = findScsiDevice(ip, target, lun, ne) + dev, err = findScsiDevice(ip, target, lun, nsexec) if err == nil { break } @@ -173,11 +168,12 @@ func GetDevice(ip, target string, lun int, ne *util.NamespaceExecutor) (*util.Ke } // IsTargetLoggedIn check all portals if ip == "" -func IsTargetLoggedIn(ip, target string, ne *util.NamespaceExecutor) bool { +func IsTargetLoggedIn(ip, target string, nsexec *lhns.Executor) bool { opts := []string{ "-m", "session", } - output, err := ne.Execute(iscsiBinary, opts) + + output, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return false } @@ -202,25 +198,25 @@ func IsTargetLoggedIn(ip, target string, ne *util.NamespaceExecutor) bool { return found } -func manualScanSession(ip, target string, ne *util.NamespaceExecutor) error { +func manualScanSession(ip, target string, nsexec *lhns.Executor) error { opts := []string{ "-m", "node", "-T", target, "-p", ip, "--rescan", } - _, err := ne.ExecuteWithTimeout(ScanTimeout, iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, ScanTimeout) return err } -func getIscsiNodeSessionScanMode(ip, target string, ne *util.NamespaceExecutor) (string, error) { +func getIscsiNodeSessionScanMode(ip, target string, nsexec *lhns.Executor) (string, error) { opts := []string{ "-m", "node", "-T", target, "-p", ip, "-o", "show", } - output, err := ne.ExecuteWithTimeout(ScanTimeout, iscsiBinary, opts) + output, err := nsexec.Execute(nil, iscsiBinary, opts, ScanTimeout) if err != nil { return "", err } @@ -230,14 +226,14 @@ func getIscsiNodeSessionScanMode(ip, target string, ne *util.NamespaceExecutor) return scanModeAuto, nil } -func findScsiDevice(ip, target string, lun int, ne *util.NamespaceExecutor) (*util.KernelDevice, error) { +func findScsiDevice(ip, target string, lun int, nsexec *lhns.Executor) (*lhtypes.BlockDeviceInfo, error) { name := "" opts := []string{ "-m", "session", "-P", "3", } - output, err := ne.Execute(iscsiBinary, opts) + output, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return nil, err } @@ -302,8 +298,9 @@ func findScsiDevice(ip, target string, lun int, ne *util.NamespaceExecutor) (*ut return nil, fmt.Errorf("cannot find iSCSI device") } + // TODO: replace with namespace joiner // now that we know the device is mapped, we can get it's (major:minor) - devices, err := util.GetKnownDevices(ne) + devices, err := lhns.GetSystemBlockDevices() if err != nil { return nil, err } @@ -313,43 +310,50 @@ func findScsiDevice(ip, target string, lun int, ne *util.NamespaceExecutor) (*ut return nil, fmt.Errorf("cannot find kernel device for iSCSI device: %s", name) } - return dev, nil + return &dev, nil } -func CleanupScsiNodes(target string, ne *util.NamespaceExecutor) error { +func CleanupScsiNodes(target string) error { for _, dir := range ScsiNodesDirs { - if _, err := ne.Execute("ls", []string{dir}); err != nil { + if _, err := lhns.GetFileInfo(dir); err != nil { continue } + targetDir := filepath.Join(dir, target) - if _, err := ne.Execute("ls", []string{targetDir}); err != nil { + if _, err := lhns.GetFileInfo(targetDir); err != nil { continue } + // Remove all empty files in the directory - output, err := ne.Execute("find", []string{targetDir}) + emptyFilePaths, err := lhns.GetEmptyFiles(targetDir) if err != nil { - return errors.Wrapf(err, "failed to search iSCSI directory %v", targetDir) + return err } - scanner := bufio.NewScanner(strings.NewReader(output)) - for scanner.Scan() { - file := scanner.Text() - output, err := ne.Execute("stat", []string{file}) + + for _, emptyFilePath := range emptyFilePaths { + err := lhns.DeletePath(emptyFilePath) if err != nil { - return errors.Wrapf(err, "failed to check iSCSI node file %v", file) + return errors.Wrapf(err, "failed to clean up empty iSCSI node file %v", emptyFilePath) } - if strings.Contains(output, "regular empty file") { - if _, err := ne.Execute("rm", []string{file}); err != nil { - return errors.Wrapf(err, "failed to clean up empty iSCSI node file %v", file) - } - // We're trying to clean up the upper level directory as well, but won't mind if we fail - _, _ = ne.Execute("rmdir", []string{filepath.Dir(file)}) + } + + // Try to remove the upper level directory containing empty files. + // We don't mind if it fails. + dirContainEmptyFiles := make(map[string]bool) + for _, emptyFilePath := range emptyFilePaths { + dirContainEmptyFiles[filepath.Dir(emptyFilePath)] = true + } + for dir := range dirContainEmptyFiles { + err := lhns.DeleteDirectory(dir) + if err != nil { + logrus.WithError(err).Warnf("Failed to clean up iSCSI node directory %v", dir) } } } return nil } -func RescanTarget(ip, target string, ne *util.NamespaceExecutor) error { +func RescanTarget(ip, target string, nsexec *lhns.Executor) error { opts := []string{ "-m", "node", "-T", target, @@ -358,6 +362,6 @@ func RescanTarget(ip, target string, ne *util.NamespaceExecutor) error { if ip != "" { opts = append(opts, "-p", ip) } - _, err := ne.Execute(iscsiBinary, opts) + _, err := nsexec.Execute(nil, iscsiBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } diff --git a/vendor/github.com/longhorn/go-iscsi-helper/iscsi/target.go b/vendor/github.com/longhorn/go-iscsi-helper/iscsi/target.go index 5091a0c244..640766a9b6 100644 --- a/vendor/github.com/longhorn/go-iscsi-helper/iscsi/target.go +++ b/vendor/github.com/longhorn/go-iscsi-helper/iscsi/target.go @@ -12,7 +12,8 @@ import ( "github.com/pkg/errors" - "github.com/longhorn/go-iscsi-helper/util" + lhtypes "github.com/longhorn/go-common-libs/types" + lhexec "github.com/longhorn/go-common-libs/exec" ) var ( @@ -39,7 +40,7 @@ func CreateTarget(tid int, name string) error { "--tid", strconv.Itoa(tid), "-T", name, } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -51,7 +52,7 @@ func DeleteTarget(tid int) error { "--mode", "target", "--tid", strconv.Itoa(tid), } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -66,7 +67,7 @@ func AddLunBackedByFile(tid int, lun int, backingFile string) error { "--lun", strconv.Itoa(lun), "-b", backingFile, } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -88,7 +89,7 @@ func AddLun(tid int, lun int, backingFile string, bstype string, bsopts string) if bsopts != "" { opts = append(opts, "--bsopts", bsopts) } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -108,7 +109,7 @@ func UpdateLun(tid int, lun int, params map[string]string) error { } opts = append(opts, "--params", strings.TrimSuffix(paramStr, ",")) } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -135,7 +136,7 @@ func DeleteLun(tid int, lun int) error { "--tid", strconv.Itoa(tid), "--lun", strconv.Itoa(lun), } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -150,7 +151,7 @@ func ExpandLun(tid, lun int, size int64) error { "--lun", strconv.Itoa(lun), "--params", fmt.Sprintf("bsopts=size=%d", size), } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -164,7 +165,7 @@ func BindInitiator(tid int, initiator string) error { "--tid", strconv.Itoa(tid), "-I", initiator, } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -178,7 +179,7 @@ func UnbindInitiator(tid int, initiator string) error { "--tid", strconv.Itoa(tid), "-I", initiator, } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -240,7 +241,7 @@ func CheckTargetForBackingStore(name string) bool { "--op", "show", "--mode", "system", } - output, err := util.Execute(tgtBinary, opts) + output, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return false } @@ -255,7 +256,7 @@ func GetTargetTid(name string) (int, error) { "--op", "show", "--mode", "target", } - output, err := util.Execute(tgtBinary, opts) + output, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return -1, err } @@ -287,7 +288,7 @@ func ShutdownTgtd() error { "--op", "delete", "--mode", "system", } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -298,7 +299,7 @@ func GetTargetConnections(tid int) (map[string][]string, error) { "--mode", "conn", "--tid", strconv.Itoa(tid), } - output, err := util.Execute(tgtBinary, opts) + output, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return nil, err } @@ -361,7 +362,7 @@ func CloseConnection(tid int, sid, cid string) error { "--sid", sid, "--cid", cid, } - _, err := util.Execute(tgtBinary, opts) + _, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) return err } @@ -372,7 +373,7 @@ func FindNextAvailableTargetID() (int, error) { "--op", "show", "--mode", "target", } - output, err := util.Execute(tgtBinary, opts) + output, err := lhexec.NewExecutor().Execute(nil, tgtBinary, opts, lhtypes.ExecuteDefaultTimeout) if err != nil { return -1, err } diff --git a/vendor/github.com/longhorn/go-iscsi-helper/types/tgtadm_errors.go b/vendor/github.com/longhorn/go-iscsi-helper/types/tgtadm_errors.go index 809278963d..1b7215c12a 100644 --- a/vendor/github.com/longhorn/go-iscsi-helper/types/tgtadm_errors.go +++ b/vendor/github.com/longhorn/go-iscsi-helper/types/tgtadm_errors.go @@ -1,6 +1,6 @@ package types -// erros are from tgt/usr/tgtadm_error.h and tgt/usr/tgtadm.c +// errors are from tgt/usr/tgtadm_error.h and tgt/usr/tgtadm.c const ( TgtadmSuccess = "success" TgtadmUnknown = "unknown error" diff --git a/vendor/github.com/longhorn/go-iscsi-helper/util/process.go b/vendor/github.com/longhorn/go-iscsi-helper/util/process.go index 2fe035a731..54412f5194 100644 --- a/vendor/github.com/longhorn/go-iscsi-helper/util/process.go +++ b/vendor/github.com/longhorn/go-iscsi-helper/util/process.go @@ -3,63 +3,16 @@ package util import ( "fmt" - linuxproc "github.com/c9s/goprocinfo/linux" + lhproc "github.com/longhorn/go-common-libs/proc" ) -const ( - DockerdProcess = "dockerd" - ContainerdProcess = "containerd" - ContainerdProcessShim = "containerd-shim" -) - -type ProcessFinder struct { - procPath string -} - -func NewProcessFinder(procPath string) *ProcessFinder { - return &ProcessFinder{procPath} -} - -func (p *ProcessFinder) FindPid(pid int64) (*linuxproc.ProcessStatus, error) { - path := fmt.Sprintf("%s/%d/status", p.procPath, pid) - return linuxproc.ReadProcessStatus(path) -} +const ISCSIdProcess = "iscsid" -func (p *ProcessFinder) FindSelf() (*linuxproc.ProcessStatus, error) { - path := fmt.Sprintf("%s/self/status", p.procPath) - return linuxproc.ReadProcessStatus(path) -} - -func (p *ProcessFinder) FindAncestorByName(ancestorProcess string) (*linuxproc.ProcessStatus, error) { - ps, err := p.FindSelf() +func GetISCSIdNamespaceDirectory(procDir string) (string, error) { + pids, err := lhproc.GetProcessPIDs(ISCSIdProcess, procDir) if err != nil { - return nil, err - } - - for { - if ps.Name == ancestorProcess { - return ps, nil - } - if ps.PPid == 0 { - break - } - ps, err = p.FindPid(ps.PPid) - if err != nil { - return nil, err - } + return "", err } - return nil, fmt.Errorf("failed to find the ancestor process: %s", ancestorProcess) -} - -func GetHostNamespacePath(hostProcPath string) string { - pf := NewProcessFinder(hostProcPath) - containerNames := []string{DockerdProcess, ContainerdProcess, ContainerdProcessShim} - for _, name := range containerNames { - proc, err := pf.FindAncestorByName(name) - if err == nil { - return fmt.Sprintf("%s/%d/ns/", hostProcPath, proc.Pid) - } - } - return fmt.Sprintf("%s/%d/ns/", hostProcPath, 1) + return lhproc.GetNamespaceDirectory(procDir, fmt.Sprint(pids[0])), nil } diff --git a/vendor/github.com/longhorn/go-iscsi-helper/util/util.go b/vendor/github.com/longhorn/go-iscsi-helper/util/util.go index 220b12080b..a51a2b7075 100644 --- a/vendor/github.com/longhorn/go-iscsi-helper/util/util.go +++ b/vendor/github.com/longhorn/go-iscsi-helper/util/util.go @@ -1,37 +1,20 @@ package util import ( - "bufio" - "bytes" "fmt" - "io" "net" "os" - "os/exec" - "path/filepath" + "strings" "time" "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" -) - -const ( - NSBinary = "nsenter" - LSBLKBinary = "lsblk" -) -var ( - cmdTimeout = time.Minute // one minute by default + lhtypes "github.com/longhorn/go-common-libs/types" ) -type KernelDevice struct { - Name string - Major int - Minor int -} - func getIPFromAddrs(addrs []net.Addr) string { for _, addr := range addrs { if ip, ok := addr.(*net.IPNet); ok && ip.IP.IsGlobalUnicast() { @@ -72,174 +55,6 @@ func GetIPToHost() (string, error) { return "", fmt.Errorf("cannot find IP connect to the host") } -type NamespaceExecutor struct { - ns string -} - -func NewNamespaceExecutor(ns string) (*NamespaceExecutor, error) { - ne := &NamespaceExecutor{ - ns: ns, - } - - if ns == "" { - return ne, nil - } - mntNS := filepath.Join(ns, "mnt") - netNS := filepath.Join(ns, "net") - if _, err := Execute(NSBinary, []string{"-V"}); err != nil { - return nil, errors.Wrap(err, "cannot find nsenter for namespace switching") - } - if _, err := Execute(NSBinary, []string{"--mount=" + mntNS, "mount"}); err != nil { - return nil, errors.Wrapf(err, "invalid mount namespace %v", mntNS) - } - if _, err := Execute(NSBinary, []string{"--net=" + netNS, "ip", "addr"}); err != nil { - return nil, errors.Wrapf(err, "invalid net namespace %v", netNS) - } - return ne, nil -} - -func (ne *NamespaceExecutor) prepareCommandArgs(name string, args []string) []string { - cmdArgs := []string{ - "--mount=" + filepath.Join(ne.ns, "mnt"), - "--net=" + filepath.Join(ne.ns, "net"), - name, - } - return append(cmdArgs, args...) -} - -func (ne *NamespaceExecutor) Execute(name string, args []string) (string, error) { - if ne.ns == "" { - return Execute(name, args) - } - return Execute(NSBinary, ne.prepareCommandArgs(name, args)) -} - -func (ne *NamespaceExecutor) ExecuteWithTimeout(timeout time.Duration, name string, args []string) (string, error) { - if ne.ns == "" { - return ExecuteWithTimeout(timeout, name, args) - } - return ExecuteWithTimeout(timeout, NSBinary, ne.prepareCommandArgs(name, args)) -} - -func (ne *NamespaceExecutor) ExecuteWithoutTimeout(name string, args []string) (string, error) { - if ne.ns == "" { - return ExecuteWithoutTimeout(name, args) - } - return ExecuteWithoutTimeout(NSBinary, ne.prepareCommandArgs(name, args)) -} - -func Execute(binary string, args []string) (string, error) { - return ExecuteWithTimeout(cmdTimeout, binary, args) -} - -func ExecuteWithTimeout(timeout time.Duration, binary string, args []string) (string, error) { - var err error - cmd := exec.Command(binary, args...) - done := make(chan struct{}) - - var output, stderr bytes.Buffer - cmd.Stdout = &output - cmd.Stderr = &stderr - - go func() { - err = cmd.Run() - done <- struct{}{} - }() - - select { - case <-done: - case <-time.After(timeout): - if cmd.Process != nil { - if err := cmd.Process.Kill(); err != nil { - logrus.Warnf("Problem killing process pid=%v: %s", cmd.Process.Pid, err) - } - - } - return "", errors.Wrapf(err, "timeout executing: %v %v, output %s, stderr %s", - binary, args, output.String(), stderr.String()) - } - - if err != nil { - return "", errors.Wrapf(err, "failed to execute: %v %v, output %s, stderr %s", - binary, args, output.String(), stderr.String()) - } - return output.String(), nil -} - -// TODO: Merge this with ExecuteWithTimeout - -func ExecuteWithoutTimeout(binary string, args []string) (string, error) { - var err error - var output, stderr bytes.Buffer - - cmd := exec.Command(binary, args...) - cmd.Stdout = &output - cmd.Stderr = &stderr - - if err = cmd.Run(); err != nil { - return "", errors.Wrapf(err, "failed to execute: %v %v, output %s, stderr %s", - binary, args, output.String(), stderr.String()) - } - return output.String(), nil -} - -func (ne *NamespaceExecutor) ExecuteWithStdin(name string, args []string, stdinString string) (string, error) { - if ne.ns == "" { - return ExecuteWithStdin(name, args, stdinString) - } - cmdArgs := []string{ - "--mount=" + filepath.Join(ne.ns, "mnt"), - "--net=" + filepath.Join(ne.ns, "net"), - name, - } - cmdArgs = append(cmdArgs, args...) - return ExecuteWithStdin(NSBinary, cmdArgs, stdinString) -} - -func ExecuteWithStdin(binary string, args []string, stdinString string) (string, error) { - var err error - cmd := exec.Command(binary, args...) - done := make(chan struct{}) - - var output, stderr bytes.Buffer - cmd.Stdout = &output - cmd.Stderr = &stderr - - stdin, err := cmd.StdinPipe() - if err != nil { - return "", err - } - - go func() { - defer stdin.Close() - io.WriteString(stdin, stdinString) - }() - - go func() { - err = cmd.Run() - done <- struct{}{} - }() - - select { - case <-done: - case <-time.After(cmdTimeout): - if cmd.Process != nil { - if err := cmd.Process.Kill(); err != nil { - logrus.Warnf("Problem killing process pid=%v: %s", cmd.Process.Pid, err) - } - - } - return "", errors.Wrapf(err, "timeout executing: %v %v, output %s, stderr %s", - binary, args, output.String(), stderr.String()) - } - - if err != nil { - return "", errors.Wrapf(err, "failed to execute: %v %v, output %s, stderr %s", - binary, args, output.String(), stderr.String()) - } - return output.String(), nil -} - func RemoveFile(file string) error { if _, err := os.Stat(file); os.IsNotExist(err) { // file doesn't exist @@ -262,54 +77,18 @@ func RemoveDevice(dev string) error { return nil } -func GetKnownDevices(ne *NamespaceExecutor) (map[string]*KernelDevice, error) { - knownDevices := make(map[string]*KernelDevice) - - /* Example command output - $ lsblk -l -n -o NAME,MAJ:MIN - sda 8:0 - sdb 8:16 - sdc 8:32 - nvme0n1 259:0 - nvme0n1p1 259:1 - nvme0n1p128 259:2 - nvme1n1 259:3 - */ - - opts := []string{ - "-l", "-n", "-o", "NAME,MAJ:MIN", - } - - output, err := ne.Execute(LSBLKBinary, opts) - if err != nil { - return knownDevices, err - } - - scanner := bufio.NewScanner(strings.NewReader(output)) - for scanner.Scan() { - line := scanner.Text() - f := strings.Fields(line) - if len(f) == 2 { - dev := &KernelDevice{ - Name: f[0], - } - if _, err := fmt.Sscanf(f[1], "%d:%d", &dev.Major, &dev.Minor); err != nil { - return nil, fmt.Errorf("invalid major:minor %s for device %s", dev.Name, f[1]) - } - knownDevices[dev.Name] = dev - } - } - - return knownDevices, nil -} - -func DuplicateDevice(dev *KernelDevice, dest string) error { +func DuplicateDevice(dev *lhtypes.BlockDeviceInfo, dest string) error { if err := mknod(dest, dev.Major, dev.Minor); err != nil { return errors.Wrapf(err, "cannot create device node %s for device %s", dest, dev.Name) } if err := os.Chmod(dest, 0660); err != nil { return errors.Wrapf(err, "cannot change permission of the device %s", dest) } + // We use the group 6 by default because this is common group for disks + // See more at https://github.com/longhorn/longhorn/issues/8088#issuecomment-1982300242 + if err := os.Chown(dest, 0, 6); err != nil { + return errors.Wrapf(err, "cannot change ownership of the device %s", dest) + } return nil } diff --git a/vendor/github.com/longhorn/longhorn-engine/pkg/util/util.go b/vendor/github.com/longhorn/longhorn-engine/pkg/util/util.go index 908528d2a4..d1e11204f3 100644 --- a/vendor/github.com/longhorn/longhorn-engine/pkg/util/util.go +++ b/vendor/github.com/longhorn/longhorn-engine/pkg/util/util.go @@ -8,21 +8,16 @@ import ( "net/url" "os" "path/filepath" - "reflect" "regexp" - "runtime" "strconv" "strings" "syscall" "time" - "github.com/google/uuid" "github.com/gorilla/handlers" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" - iutil "github.com/longhorn/go-iscsi-helper/util" - "github.com/longhorn/longhorn-engine/pkg/types" ) @@ -30,8 +25,6 @@ var ( MaximumVolumeNameSize = 64 validVolumeName = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]+$`) - HostProc = "/host/proc" - unixDomainSocketDirectoryInContainer = "/host/var/lib/longhorn/unix-domain-socket/" ) @@ -87,10 +80,6 @@ func GetPortFromAddress(address string) (int, error) { return port, nil } -func UUID() string { - return uuid.New().String() -} - func Filter(list []string, check func(string) bool) []string { result := make([]string, 0, len(list)) for _, i := range list { @@ -101,15 +90,6 @@ func Filter(list []string, check func(string) bool) []string { return result } -func Contains(arr []string, val string) bool { - for _, a := range arr { - if a == val { - return true - } - } - return false -} - type filteredLoggingHandler struct { filteredPaths map[string]struct{} handler http.Handler @@ -292,18 +272,6 @@ func ResolveBackingFilepath(fileOrDirpath string) (string, error) { return fileOrDirpath, nil } -func GetInitiatorNS() string { - return iutil.GetHostNamespacePath(HostProc) -} - -func GetFunctionName(i interface{}) string { - return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() -} - -func RandomID(randomIDLenth int) string { - return UUID()[:randomIDLenth] -} - func GetAddresses(volumeName, address string, dataServerProtocol types.DataServerProtocol) (string, string, string, int, error) { switch dataServerProtocol { case types.DataServerProtocolTCP: diff --git a/vendor/github.com/longhorn/longhorn-instance-manager/pkg/util/util.go b/vendor/github.com/longhorn/longhorn-instance-manager/pkg/util/util.go index d7b92493a9..dd3c304cd5 100644 --- a/vendor/github.com/longhorn/longhorn-instance-manager/pkg/util/util.go +++ b/vendor/github.com/longhorn/longhorn-instance-manager/pkg/util/util.go @@ -138,15 +138,6 @@ func IsSPDKTgtReady(timeout time.Duration) bool { return false } -func IsMountPointReadOnly(mp mount.MountPoint) bool { - for _, opt := range mp.Opts { - if opt == "ro" { - return true - } - } - return false -} - func GetVolumeMountPointMap() (map[string]mount.MountPoint, error) { volumeMountPointMap := make(map[string]mount.MountPoint) diff --git a/vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/crypto.go b/vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/crypto.go index 2a6daf3ff7..a2599a7000 100644 --- a/vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/crypto.go +++ b/vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/crypto.go @@ -4,15 +4,25 @@ import ( "fmt" "strings" - "github.com/longhorn/longhorn-share-manager/pkg/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" + + lhns "github.com/longhorn/go-common-libs/ns" + lhtypes "github.com/longhorn/go-common-libs/types" + + "github.com/longhorn/longhorn-share-manager/pkg/types" ) // EncryptVolume encrypts provided device with LUKS. func EncryptVolume(devicePath, passphrase, keyCipher, keyHash, keySize, pbkdf string) error { + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.HostProcDirectory, namespaces) + if err != nil { + return err + } + logrus.Debugf("Encrypting device %s with LUKS", devicePath) - if _, err := luksFormat(devicePath, passphrase, keyCipher, keyHash, keySize, pbkdf); err != nil { + if _, err := nsexec.LuksFormat(devicePath, passphrase, keyCipher, keyHash, keySize, pbkdf, lhtypes.LuksTimeout); err != nil { return errors.Wrapf(err, "failed to encrypt device %s with LUKS", devicePath) } return nil @@ -26,8 +36,14 @@ func OpenVolume(volume, devicePath, passphrase string) error { return nil } + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.HostProcDirectory, namespaces) + if err != nil { + return err + } + logrus.Debugf("Opening device %s with LUKS on %s", devicePath, volume) - _, err := luksOpen(volume, devicePath, passphrase) + _, err = nsexec.LuksOpen(volume, devicePath, passphrase, lhtypes.LuksTimeout) if err != nil { logrus.WithError(err).Warnf("Failed to open LUKS device %s", devicePath) } @@ -36,8 +52,14 @@ func OpenVolume(volume, devicePath, passphrase string) error { // CloseVolume closes encrypted volume so it can be detached. func CloseVolume(volume string) error { + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.HostProcDirectory, namespaces) + if err != nil { + return err + } + logrus.Debugf("Closing LUKS device %s", volume) - _, err := luksClose(volume) + _, err = nsexec.LuksClose(volume, lhtypes.LuksTimeout) return err } @@ -54,8 +76,15 @@ func DeviceEncryptionStatus(devicePath string) (mappedDevice, mapper string, err if !strings.HasPrefix(devicePath, types.MapperDevPath) { return devicePath, "", nil } + + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceIpc} + nsexec, err := lhns.NewNamespaceExecutor(lhtypes.ProcessNone, lhtypes.HostProcDirectory, namespaces) + if err != nil { + return devicePath, "", err + } + volume := strings.TrimPrefix(devicePath, types.MapperDevPath+"/") - stdout, err := luksStatus(volume) + stdout, err := nsexec.LuksStatus(volume, lhtypes.LuksTimeout) if err != nil { logrus.WithError(err).Debugf("Device %s is not an active LUKS device", devicePath) return devicePath, "", nil diff --git a/vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/luks.go b/vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/luks.go deleted file mode 100644 index 69330785ed..0000000000 --- a/vendor/github.com/longhorn/longhorn-share-manager/pkg/crypto/luks.go +++ /dev/null @@ -1,77 +0,0 @@ -package crypto - -import ( - "bytes" - "context" - "fmt" - "os/exec" - "path/filepath" - "strings" - "time" - - iscsi_util "github.com/longhorn/go-iscsi-helper/util" -) - -const hostProcPath = "/host/proc" -const luksTimeout = time.Minute - -func luksOpen(volume, devicePath, passphrase string) (stdout string, err error) { - return cryptSetupWithPassphrase(passphrase, - "luksOpen", devicePath, volume, "-d", "/dev/stdin") -} - -func luksClose(volume string) (stdout string, err error) { - return cryptSetup("luksClose", volume) -} - -func luksFormat(devicePath, passphrase, keyCipher, keyHash, keySize, pbkdf string) (stdout string, err error) { - return cryptSetupWithPassphrase(passphrase, - "-q", "luksFormat", "--type", "luks2", "--cipher", keyCipher, "--hash", keyHash, "--key-size", keySize, "--pbkdf", pbkdf, - devicePath, "-d", "/dev/stdin") -} - -func luksStatus(volume string) (stdout string, err error) { - return cryptSetup("status", volume) -} - -func cryptSetup(args ...string) (stdout string, err error) { - return cryptSetupWithPassphrase("", args...) -} - -// cryptSetupWithPassphrase runs cryptsetup via nsenter inside of the host namespaces -// cryptsetup returns 0 on success and a non-zero value on error. -// 1 wrong parameters, 2 no permission (bad passphrase), -// 3 out of memory, 4 wrong device specified, -// 5 device already exists or device is busy. -func cryptSetupWithPassphrase(passphrase string, args ...string) (stdout string, err error) { - // NOTE: cryptsetup needs to be run in the host IPC/MNT - // if you only use MNT the binary will not return but still do the appropriate action. - ns := iscsi_util.GetHostNamespacePath(hostProcPath) - // ns := fmt.Sprintf("%s/%d/ns/", hostProcPath, 1) - nsArgs := prepareCommandArgs(ns, "cryptsetup", args) - ctx, cancel := context.WithTimeout(context.TODO(), luksTimeout) - defer cancel() - cmd := exec.CommandContext(ctx, "nsenter", nsArgs...) - - var stdoutBuf bytes.Buffer - cmd.Stdout = &stdoutBuf - if len(passphrase) > 0 { - cmd.Stdin = strings.NewReader(passphrase) - } - - output := string(stdoutBuf.Bytes()) - if err := cmd.Run(); err != nil { - return output, fmt.Errorf("failed to run cryptsetup args: %v output: %v error: %v", args, output, err) - } - - return stdoutBuf.String(), nil -} - -func prepareCommandArgs(ns, cmd string, args []string) []string { - cmdArgs := []string{ - "--mount=" + filepath.Join(ns, "mnt"), - "--ipc=" + filepath.Join(ns, "ipc"), - cmd, - } - return append(cmdArgs, args...) -} diff --git a/vendor/github.com/longhorn/longhorn-share-manager/pkg/rpc/server.go b/vendor/github.com/longhorn/longhorn-share-manager/pkg/rpc/server.go index 60c989c31c..3989f176f7 100644 --- a/vendor/github.com/longhorn/longhorn-share-manager/pkg/rpc/server.go +++ b/vendor/github.com/longhorn/longhorn-share-manager/pkg/rpc/server.go @@ -1,25 +1,26 @@ package smrpc import ( - fmt "fmt" - "io/ioutil" + "fmt" + "os" "strings" "sync" "time" + "github.com/golang/protobuf/ptypes/empty" "github.com/google/fscrypt/filesystem" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "golang.org/x/net/context" "k8s.io/mount-utils" - empty "github.com/golang/protobuf/ptypes/empty" - "golang.org/x/net/context" grpccodes "google.golang.org/grpc/codes" healthpb "google.golang.org/grpc/health/grpc_health_v1" grpcstatus "google.golang.org/grpc/status" - iscsiutil "github.com/longhorn/go-iscsi-helper/util" + lhns "github.com/longhorn/go-common-libs/ns" + lhtypes "github.com/longhorn/go-common-libs/types" "github.com/longhorn/longhorn-share-manager/pkg/server" "github.com/longhorn/longhorn-share-manager/pkg/server/nfs" @@ -99,11 +100,17 @@ func (s *ShareManagerServer) FilesystemTrim(ctx context.Context, req *Filesystem return &empty.Empty{}, grpcstatus.Error(grpccodes.Internal, err.Error()) } - if _, err := ioutil.ReadDir(mountPath); err != nil { + if _, err := os.ReadDir(mountPath); err != nil { + return &empty.Empty{}, grpcstatus.Error(grpccodes.Internal, err.Error()) + } + + namespaces := []lhtypes.Namespace{lhtypes.NamespaceMnt, lhtypes.NamespaceNet} + nsexec, err := lhns.NewNamespaceExecutor(lhns.GetDefaultProcessName(), lhtypes.HostProcDirectory, namespaces) + if err != nil { return &empty.Empty{}, grpcstatus.Error(grpccodes.Internal, err.Error()) } - _, err = iscsiutil.Execute("fstrim", []string{mountPath}) + _, err = nsexec.Execute(nil, lhtypes.BinaryFstrim, []string{mountPath}, lhtypes.ExecuteDefaultTimeout) if err != nil { return &empty.Empty{}, grpcstatus.Error(grpccodes.Internal, err.Error()) } diff --git a/vendor/github.com/longhorn/longhorn-share-manager/pkg/server/share_manager.go b/vendor/github.com/longhorn/longhorn-share-manager/pkg/server/share_manager.go index 9cdcbeee22..baa64ab57b 100644 --- a/vendor/github.com/longhorn/longhorn-share-manager/pkg/server/share_manager.go +++ b/vendor/github.com/longhorn/longhorn-share-manager/pkg/server/share_manager.go @@ -15,6 +15,8 @@ import ( "github.com/longhorn/longhorn-share-manager/pkg/server/nfs" "github.com/longhorn/longhorn-share-manager/pkg/types" "github.com/longhorn/longhorn-share-manager/pkg/volume" + + commonUtils "github.com/longhorn/go-common-libs/utils" ) const waitBetweenChecks = time.Second * 5 @@ -246,7 +248,7 @@ func (m *ShareManager) hasHealthyVolume() error { mounter := mount.New("") mountPoints, _ := mounter.List() for _, mp := range mountPoints { - if mp.Path == mountPath && isMountPointReadOnly(mp) { + if mp.Path == mountPath && commonUtils.IsMountPointReadOnly(mp) { return fmt.Errorf(ReadOnlyErr, mountPath) } } @@ -279,12 +281,3 @@ func (m *ShareManager) ShareIsExported() bool { func (m *ShareManager) Shutdown() { m.shutdown() } - -func isMountPointReadOnly(mp mount.MountPoint) bool { - for _, opt := range mp.Opts { - if opt == "ro" { - return true - } - } - return false -} diff --git a/vendor/github.com/power-devops/perfstat/LICENSE b/vendor/github.com/power-devops/perfstat/LICENSE new file mode 100644 index 0000000000..ec4e5d39d8 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2020 Power DevOps + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/vendor/github.com/power-devops/perfstat/c_helpers.c b/vendor/github.com/power-devops/perfstat/c_helpers.c new file mode 100644 index 0000000000..49ba1ad7eb --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/c_helpers.c @@ -0,0 +1,159 @@ +#include "c_helpers.h" + +GETFUNC(cpu) +GETFUNC(disk) +GETFUNC(diskadapter) +GETFUNC(diskpath) +GETFUNC(fcstat) +GETFUNC(logicalvolume) +GETFUNC(memory_page) +GETFUNC(netadapter) +GETFUNC(netbuffer) +GETFUNC(netinterface) +GETFUNC(pagingspace) +GETFUNC(process) +GETFUNC(thread) +GETFUNC(volumegroup) + +double get_partition_mhz(perfstat_partition_config_t pinfo) { + return pinfo.processorMHz; +} + +char *get_ps_hostname(perfstat_pagingspace_t *ps) { + return ps->u.nfs_paging.hostname; +} + +char *get_ps_filename(perfstat_pagingspace_t *ps) { + return ps->u.nfs_paging.filename; +} + +char *get_ps_vgname(perfstat_pagingspace_t *ps) { + return ps->u.lv_paging.vgname; +} + +time_t boottime() +{ + register struct utmpx *utmp; + + setutxent(); + while ( (utmp = getutxent()) != NULL ) { + if (utmp->ut_type == BOOT_TIME) { + return utmp->ut_tv.tv_sec; + } + } + endutxent(); + return -1; +} + +struct fsinfo *get_filesystem_stat(struct fsinfo *fs_all, int n) { + if (!fs_all) return NULL; + return &(fs_all[n]); +} + +int get_mounts(struct vmount **vmountpp) { + int size; + struct vmount *vm; + int nmounts; + + size = BUFSIZ; + + while (1) { + if ((vm = (struct vmount *)malloc((size_t)size)) == NULL) { + perror("malloc failed"); + exit(-1); + } + if ((nmounts = mntctl(MCTL_QUERY, size, (caddr_t)vm)) > 0) { + *vmountpp = vm; + return nmounts; + } else if (nmounts == 0) { + size = *(int *)vm; + free((void *)vm); + } else { + free((void *)vm); + return -1; + } + } +} + +void fill_fsinfo(struct statfs statbuf, struct fsinfo *fs) { + fsblkcnt_t freeblks, totblks, usedblks; + fsblkcnt_t tinodes, ninodes, ifree; + uint cfactor; + + if (statbuf.f_blocks == -1) { + fs->totalblks = 0; + fs->freeblks = 0; + fs->totalinodes = 0; + fs->freeinodes = 0; + return; + } + + cfactor = statbuf.f_bsize / 512; + fs->freeblks = statbuf.f_bavail * cfactor; + fs->totalblks = statbuf.f_blocks * cfactor; + + fs->freeinodes = statbuf.f_ffree; + fs->totalinodes = statbuf.f_files; + + if (fs->freeblks < 0) + fs->freeblks = 0; +} + +int getfsinfo(char *fsname, char *devname, char *host, char *options, int flags, int fstype, struct fsinfo *fs) { + struct statfs statbuf; + int devname_size = strlen(devname); + int fsname_size = strlen(fsname); + char buf[BUFSIZ]; + char *p; + + if (fs == NULL) { + return 1; + } + + for (p = strtok(options, ","); p != NULL; p = strtok(NULL, ",")) + if (strcmp(p, "ignore") == 0) + return 0; + + if (*host != 0 && strcmp(host, "-") != 0) { + sprintf(buf, "%s:%s", host, devname); + devname = buf; + } + fs->devname = (char *)calloc(devname_size+1, 1); + fs->fsname = (char *)calloc(fsname_size+1, 1); + strncpy(fs->devname, devname, devname_size); + strncpy(fs->fsname, fsname, fsname_size); + fs->flags = flags; + fs->fstype = fstype; + + if (statfs(fsname,&statbuf) < 0) { + return 1; + } + + fill_fsinfo(statbuf, fs); + return 0; +} + +struct fsinfo *get_all_fs(int *rc) { + struct vmount *mnt; + struct fsinfo *fs_all; + int nmounts; + + *rc = -1; + if ((nmounts = get_mounts(&mnt)) <= 0) { + perror("Can't get mount table info"); + return NULL; + } + + fs_all = (struct fsinfo *)calloc(sizeof(struct fsinfo), nmounts); + while ((*rc)++, nmounts--) { + getfsinfo(vmt2dataptr(mnt, VMT_STUB), + vmt2dataptr(mnt, VMT_OBJECT), + vmt2dataptr(mnt, VMT_HOST), + vmt2dataptr(mnt, VMT_ARGS), + mnt->vmt_flags, + mnt->vmt_gfstype, + &fs_all[*rc]); + mnt = (struct vmount *)((char *)mnt + mnt->vmt_length); + } + return fs_all; +} diff --git a/vendor/github.com/power-devops/perfstat/c_helpers.h b/vendor/github.com/power-devops/perfstat/c_helpers.h new file mode 100644 index 0000000000..b66bc53c3c --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/c_helpers.h @@ -0,0 +1,58 @@ +#ifndef C_HELPERS_H +#define C_HELPERS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GETFUNC(TYPE) perfstat_##TYPE##_t *get_##TYPE##_stat(perfstat_##TYPE##_t *b, int n) { \ + if (!b) return NULL; \ + return &(b[n]); \ +} + +#define GETFUNC_EXT(TYPE) extern perfstat_##TYPE##_t *get_##TYPE##_stat(perfstat_##TYPE##_t *, int); + +GETFUNC_EXT(cpu) +GETFUNC_EXT(disk) +GETFUNC_EXT(diskadapter) +GETFUNC_EXT(diskpath) +GETFUNC_EXT(fcstat) +GETFUNC_EXT(logicalvolume) +GETFUNC_EXT(memory_page) +GETFUNC_EXT(netadapter) +GETFUNC_EXT(netbuffer) +GETFUNC_EXT(netinterface) +GETFUNC_EXT(pagingspace) +GETFUNC_EXT(process) +GETFUNC_EXT(thread) +GETFUNC_EXT(volumegroup) + +struct fsinfo { + char *devname; + char *fsname; + int flags; + int fstype; + unsigned long totalblks; + unsigned long freeblks; + unsigned long totalinodes; + unsigned long freeinodes; +}; + +extern double get_partition_mhz(perfstat_partition_config_t); +extern char *get_ps_hostname(perfstat_pagingspace_t *); +extern char *get_ps_filename(perfstat_pagingspace_t *); +extern char *get_ps_vgname(perfstat_pagingspace_t *); +extern time_t boottime(); +struct fsinfo *get_filesystem_stat(struct fsinfo *, int); +int get_mounts(struct vmount **); +void fill_statfs(struct statfs, struct fsinfo *); +int getfsinfo(char *, char *, char *, char *, int, int, struct fsinfo *); +struct fsinfo *get_all_fs(int *); + +#endif diff --git a/vendor/github.com/power-devops/perfstat/config.go b/vendor/github.com/power-devops/perfstat/config.go new file mode 100644 index 0000000000..de7230d28c --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/config.go @@ -0,0 +1,18 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +*/ +import "C" + +func EnableLVMStat() { + C.perfstat_config(C.PERFSTAT_ENABLE|C.PERFSTAT_LV|C.PERFSTAT_VG, nil) +} + +func DisableLVMStat() { + C.perfstat_config(C.PERFSTAT_DISABLE|C.PERFSTAT_LV|C.PERFSTAT_VG, nil) +} diff --git a/vendor/github.com/power-devops/perfstat/cpustat.go b/vendor/github.com/power-devops/perfstat/cpustat.go new file mode 100644 index 0000000000..902727fb8f --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/cpustat.go @@ -0,0 +1,98 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +#include +#include + +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" + "runtime" + "time" + "unsafe" +) + +func CpuStat() ([]CPU, error) { + var cpustat *C.perfstat_cpu_t + var cpu C.perfstat_id_t + + ncpu := runtime.NumCPU() + + cpustat_len := C.sizeof_perfstat_cpu_t * C.ulong(ncpu) + cpustat = (*C.perfstat_cpu_t)(C.malloc(cpustat_len)) + defer C.free(unsafe.Pointer(cpustat)) + C.strcpy(&cpu.name[0], C.CString(C.FIRST_CPU)) + r := C.perfstat_cpu(&cpu, cpustat, C.sizeof_perfstat_cpu_t, C.int(ncpu)) + if r <= 0 { + return nil, fmt.Errorf("error perfstat_cpu()") + } + c := make([]CPU, r) + for i := 0; i < int(r); i++ { + n := C.get_cpu_stat(cpustat, C.int(i)) + if n != nil { + c[i] = perfstatcpu2cpu(n) + } + } + return c, nil +} + +func CpuTotalStat() (*CPUTotal, error) { + var cpustat *C.perfstat_cpu_total_t + + cpustat = (*C.perfstat_cpu_total_t)(C.malloc(C.sizeof_perfstat_cpu_total_t)) + defer C.free(unsafe.Pointer(cpustat)) + r := C.perfstat_cpu_total(nil, cpustat, C.sizeof_perfstat_cpu_total_t, 1) + if r <= 0 { + return nil, fmt.Errorf("error perfstat_cpu_total()") + } + c := perfstatcputotal2cputotal(cpustat) + return &c, nil +} + +func CpuUtilStat(intvl time.Duration) (*CPUUtil, error) { + var cpuutil *C.perfstat_cpu_util_t + var newt *C.perfstat_cpu_total_t + var oldt *C.perfstat_cpu_total_t + var data C.perfstat_rawdata_t + + oldt = (*C.perfstat_cpu_total_t)(C.malloc(C.sizeof_perfstat_cpu_total_t)) + newt = (*C.perfstat_cpu_total_t)(C.malloc(C.sizeof_perfstat_cpu_total_t)) + cpuutil = (*C.perfstat_cpu_util_t)(C.malloc(C.sizeof_perfstat_cpu_util_t)) + defer C.free(unsafe.Pointer(oldt)) + defer C.free(unsafe.Pointer(newt)) + defer C.free(unsafe.Pointer(cpuutil)) + + r := C.perfstat_cpu_total(nil, oldt, C.sizeof_perfstat_cpu_total_t, 1) + if r <= 0 { + return nil, fmt.Errorf("error perfstat_cpu_total()") + } + + time.Sleep(intvl) + + r = C.perfstat_cpu_total(nil, newt, C.sizeof_perfstat_cpu_total_t, 1) + if r <= 0 { + return nil, fmt.Errorf("error perfstat_cpu_total()") + } + + data._type = C.UTIL_CPU_TOTAL + data.curstat = unsafe.Pointer(newt) + data.prevstat = unsafe.Pointer(oldt) + data.sizeof_data = C.sizeof_perfstat_cpu_total_t + data.cur_elems = 1 + data.prev_elems = 1 + + r = C.perfstat_cpu_util(&data, cpuutil, C.sizeof_perfstat_cpu_util_t, 1) + if r <= 0 { + return nil, fmt.Errorf("error perfstat_cpu_util()") + } + u := perfstatcpuutil2cpuutil(cpuutil) + return &u, nil +} diff --git a/vendor/github.com/power-devops/perfstat/diskstat.go b/vendor/github.com/power-devops/perfstat/diskstat.go new file mode 100644 index 0000000000..fc70dfaa4e --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/diskstat.go @@ -0,0 +1,137 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +#include +#include +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" + "unsafe" +) + +func DiskTotalStat() (*DiskTotal, error) { + var disk C.perfstat_disk_total_t + + rc := C.perfstat_disk_total(nil, &disk, C.sizeof_perfstat_disk_total_t, 1) + if rc != 1 { + return nil, fmt.Errorf("perfstat_disk_total() error") + } + d := perfstatdisktotal2disktotal(disk) + return &d, nil +} + +func DiskAdapterStat() ([]DiskAdapter, error) { + var adapter *C.perfstat_diskadapter_t + var adptname C.perfstat_id_t + + numadpt := C.perfstat_diskadapter(nil, nil, C.sizeof_perfstat_diskadapter_t, 0) + if numadpt <= 0 { + return nil, fmt.Errorf("perfstat_diskadapter() error") + } + + adapter_len := C.sizeof_perfstat_diskadapter_t * C.ulong(numadpt) + adapter = (*C.perfstat_diskadapter_t)(C.malloc(adapter_len)) + defer C.free(unsafe.Pointer(adapter)) + C.strcpy(&adptname.name[0], C.CString(C.FIRST_DISKADAPTER)) + r := C.perfstat_diskadapter(&adptname, adapter, C.sizeof_perfstat_diskadapter_t, numadpt) + if r < 0 { + return nil, fmt.Errorf("perfstat_diskadapter() error") + } + da := make([]DiskAdapter, r) + for i := 0; i < int(r); i++ { + d := C.get_diskadapter_stat(adapter, C.int(i)) + if d != nil { + da[i] = perfstatdiskadapter2diskadapter(d) + } + } + return da, nil +} + +func DiskStat() ([]Disk, error) { + var disk *C.perfstat_disk_t + var diskname C.perfstat_id_t + + numdisk := C.perfstat_disk(nil, nil, C.sizeof_perfstat_disk_t, 0) + if numdisk <= 0 { + return nil, fmt.Errorf("perfstat_disk() error") + } + + disk_len := C.sizeof_perfstat_disk_t * C.ulong(numdisk) + disk = (*C.perfstat_disk_t)(C.malloc(disk_len)) + defer C.free(unsafe.Pointer(disk)) + C.strcpy(&diskname.name[0], C.CString(C.FIRST_DISK)) + r := C.perfstat_disk(&diskname, disk, C.sizeof_perfstat_disk_t, numdisk) + if r < 0 { + return nil, fmt.Errorf("perfstat_disk() error") + } + d := make([]Disk, r) + for i := 0; i < int(r); i++ { + ds := C.get_disk_stat(disk, C.int(i)) + if ds != nil { + d[i] = perfstatdisk2disk(ds) + } + } + return d, nil +} + +func DiskPathStat() ([]DiskPath, error) { + var diskpath *C.perfstat_diskpath_t + var pathname C.perfstat_id_t + + numpaths := C.perfstat_diskpath(nil, nil, C.sizeof_perfstat_diskpath_t, 0) + if numpaths <= 0 { + return nil, fmt.Errorf("perfstat_diskpath() error") + } + + path_len := C.sizeof_perfstat_diskpath_t * C.ulong(numpaths) + diskpath = (*C.perfstat_diskpath_t)(C.malloc(path_len)) + defer C.free(unsafe.Pointer(diskpath)) + C.strcpy(&pathname.name[0], C.CString(C.FIRST_DISKPATH)) + r := C.perfstat_diskpath(&pathname, diskpath, C.sizeof_perfstat_diskpath_t, numpaths) + if r < 0 { + return nil, fmt.Errorf("perfstat_diskpath() error") + } + d := make([]DiskPath, r) + for i := 0; i < int(r); i++ { + p := C.get_diskpath_stat(diskpath, C.int(i)) + if p != nil { + d[i] = perfstatdiskpath2diskpath(p) + } + } + return d, nil +} + +func FCAdapterStat() ([]FCAdapter, error) { + var fcstat *C.perfstat_fcstat_t + var fcname C.perfstat_id_t + + numadpt := C.perfstat_fcstat(nil, nil, C.sizeof_perfstat_fcstat_t, 0) + if numadpt <= 0 { + return nil, fmt.Errorf("perfstat_fcstat() error") + } + + fcstat_len := C.sizeof_perfstat_fcstat_t * C.ulong(numadpt) + fcstat = (*C.perfstat_fcstat_t)(C.malloc(fcstat_len)) + defer C.free(unsafe.Pointer(fcstat)) + C.strcpy(&fcname.name[0], C.CString(C.FIRST_NETINTERFACE)) + r := C.perfstat_fcstat(&fcname, fcstat, C.sizeof_perfstat_fcstat_t, numadpt) + if r < 0 { + return nil, fmt.Errorf("perfstat_fcstat() error") + } + fca := make([]FCAdapter, r) + for i := 0; i < int(r); i++ { + f := C.get_fcstat_stat(fcstat, C.int(i)) + if f != nil { + fca[i] = perfstatfcstat2fcadapter(f) + } + } + return fca, nil +} diff --git a/vendor/github.com/power-devops/perfstat/doc.go b/vendor/github.com/power-devops/perfstat/doc.go new file mode 100644 index 0000000000..85eaf3e7ed --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/doc.go @@ -0,0 +1,315 @@ +// +build !aix + +// Copyright 2020 Power-Devops.com. All rights reserved. +// Use of this source code is governed by the license +// that can be found in the LICENSE file. +/* +Package perfstat is Go interface to IBM AIX libperfstat. +To use it you need AIX with installed bos.perf.libperfstat. You can check, if is installed using the following command: + + $ lslpp -L bos.perf.perfstat + +The package is written using Go 1.14.7 and AIX 7.2 TL5. It should work with earlier TLs of AIX 7.2, but I +can't guarantee that perfstat structures in the TLs have all the same fields as the structures in AIX 7.2 TL5. + +For documentation of perfstat on AIX and using it in programs refer to the official IBM documentation: +https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat.html +*/ +package perfstat + +import ( + "fmt" + "time" +) + +// EnableLVMStat() switches on LVM (logical volumes and volume groups) performance statistics. +// With this enabled you can use fields KBReads, KBWrites, and IOCnt +// in LogicalVolume and VolumeGroup data types. +func EnableLVMStat() {} + +// DisableLVMStat() switchess of LVM (logical volumes and volume groups) performance statistics. +// This is the default state. In this case LogicalVolume and VolumeGroup data types are +// populated with informations about LVM structures, but performance statistics fields +// (KBReads, KBWrites, IOCnt) are empty. +func DisableLVMStat() {} + +// CpuStat() returns array of CPU structures with information about +// logical CPUs on the system. +// IBM documentation: +// * https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_int_cpu.html +// * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cpu.html +func CpuStat() ([]CPU, error) { + return nil, fmt.Errorf("not implemented") +} + +// CpuTotalStat() returns general information about CPUs on the system. +// IBM documentation: +// * https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_glob_cpu.html +// * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cputot.html +func CpuTotalStat() (*CPUTotal, error) { + return nil, fmt.Errorf("not implemented") +} + +// CpuUtilStat() calculates CPU utilization. +// IBM documentation: +// * https://www.ibm.com/support/knowledgecenter/ssw_aix_72/performancetools/idprftools_perfstat_cpu_util.html +// * https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/p_bostechref/perfstat_cpu_util.html +func CpuUtilStat(intvl time.Duration) (*CPUUtil, error) { + return nil, fmt.Errorf("not implemented") +} + +func DiskTotalStat() (*DiskTotal, error) { + return nil, fmt.Errorf("not implemented") +} + +func DiskAdapterStat() ([]DiskAdapter, error) { + return nil, fmt.Errorf("not implemented") +} + +func DiskStat() ([]Disk, error) { + return nil, fmt.Errorf("not implemented") +} + +func DiskPathStat() ([]DiskPath, error) { + return nil, fmt.Errorf("not implemented") +} + +func FCAdapterStat() ([]FCAdapter, error) { + return nil, fmt.Errorf("not implemented") +} + +func PartitionStat() (*PartitionConfig, error) { + return nil, fmt.Errorf("not implemented") +} + +func LogicalVolumeStat() ([]LogicalVolume, error) { + return nil, fmt.Errorf("not implemented") +} + +func VolumeGroupStat() ([]VolumeGroup, error) { + return nil, fmt.Errorf("not implemented") +} + +func MemoryTotalStat() (*MemoryTotal, error) { + return nil, fmt.Errorf("not implemented") +} + +func MemoryPageStat() ([]MemoryPage, error) { + return nil, fmt.Errorf("not implemented") +} + +func PagingSpaceStat() ([]PagingSpace, error) { + return nil, fmt.Errorf("not implemented") +} + +func NetIfaceTotalStat() (*NetIfaceTotal, error) { + return nil, fmt.Errorf("not implemented") +} + +func NetBufferStat() ([]NetBuffer, error) { + return nil, fmt.Errorf("not implemented") +} + +func NetIfaceStat() ([]NetIface, error) { + return nil, fmt.Errorf("not implemented") +} + +func NetAdapterStat() ([]NetAdapter, error) { + return nil, fmt.Errorf("not implemented") +} + +func ProcessStat() ([]Process, error) { + return nil, fmt.Errorf("not implemented") +} + +func ThreadStat() ([]Thread, error) { + return nil, fmt.Errorf("not implemented") +} + +func Sysconf(name int32) (int64, error) { + return 0, fmt.Errorf("not implemented") +} + +func GetCPUImplementation() string { + return "" +} + +func POWER9OrNewer() bool { + return false +} + +func POWER9() bool { + return false +} + +func POWER8OrNewer() bool { + return false +} + +func POWER8() bool { + return false +} + +func POWER7OrNewer() bool { + return false +} + +func POWER7() bool { + return false +} + +func HasTransactionalMemory() bool { + return false +} + +func Is64Bit() bool { + return false +} + +func IsSMP() bool { + return false +} + +func HasVMX() bool { + return false +} + +func HasVSX() bool { + return false +} + +func HasDFP() bool { + return false +} + +func HasNxGzip() bool { + return false +} + +func PksCapable() bool { + return false +} + +func PksEnabled() bool { + return false +} + +func CPUMode() string { + return "" +} + +func KernelBits() int { + return 0 +} + +func IsLPAR() bool { + return false +} + +func CpuAddCapable() bool { + return false +} + +func CpuRemoveCapable() bool { + return false +} + +func MemoryAddCapable() bool { + return false +} + +func MemoryRemoveCapable() bool { + return false +} + +func DLparCapable() bool { + return false +} + +func IsNUMA() bool { + return false +} + +func KernelKeys() bool { + return false +} + +func RecoveryMode() bool { + return false +} + +func EnhancedAffinity() bool { + return false +} + +func VTpmEnabled() bool { + return false +} + +func IsVIOS() bool { + return false +} + +func MLSEnabled() bool { + return false +} + +func SPLparCapable() bool { + return false +} + +func SPLparEnabled() bool { + return false +} + +func DedicatedLpar() bool { + return false +} + +func SPLparCapped() bool { + return false +} + +func SPLparDonating() bool { + return false +} + +func SmtCapable() bool { + return false +} + +func SmtEnabled() bool { + return false +} + +func VrmCapable() bool { + return false +} + +func VrmEnabled() bool { + return false +} + +func AmeEnabled() bool { + return false +} + +func EcoCapable() bool { + return false +} + +func EcoEnabled() bool { + return false +} + +func BootTime() (uint64, error) { + return 0, fmt.Errorf("Not implemented") +} + +func UptimeSeconds() (uint64, error) { + return 0, fmt.Errorf("Not implemented") +} + +func FileSystemStat() ([]FileSystem, error) { + return nil, fmt.Errorf("Not implemented") +} diff --git a/vendor/github.com/power-devops/perfstat/fsstat.go b/vendor/github.com/power-devops/perfstat/fsstat.go new file mode 100644 index 0000000000..27f4c06c15 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/fsstat.go @@ -0,0 +1,31 @@ +// +build aix + +package perfstat + +/* +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" +) + +func FileSystemStat() ([]FileSystem, error) { + var fsinfo *C.struct_fsinfo + var nmounts C.int + + fsinfo = C.get_all_fs(&nmounts) + if nmounts <= 0 { + return nil, fmt.Errorf("No mounts found") + } + + fs := make([]FileSystem, nmounts) + for i := 0; i < int(nmounts); i++ { + f := C.get_filesystem_stat(fsinfo, C.int(i)) + if f != nil { + fs[i] = fsinfo2filesystem(f) + } + } + return fs, nil +} diff --git a/vendor/github.com/power-devops/perfstat/helpers.go b/vendor/github.com/power-devops/perfstat/helpers.go new file mode 100644 index 0000000000..e8d6997665 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/helpers.go @@ -0,0 +1,764 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +#include + +#include "c_helpers.h" +*/ +import "C" + +func perfstatcpu2cpu(n *C.perfstat_cpu_t) CPU { + var c CPU + c.Name = C.GoString(&n.name[0]) + c.User = int64(n.user) + c.Sys = int64(n.sys) + c.Idle = int64(n.idle) + c.Wait = int64(n.wait) + c.PSwitch = int64(n.pswitch) + c.Syscall = int64(n.syscall) + c.Sysread = int64(n.sysread) + c.Syswrite = int64(n.syswrite) + c.Sysfork = int64(n.sysfork) + c.Sysexec = int64(n.sysexec) + c.Readch = int64(n.readch) + c.Writech = int64(n.writech) + c.Bread = int64(n.bread) + c.Bwrite = int64(n.bwrite) + c.Lread = int64(n.lread) + c.Lwrite = int64(n.lwrite) + c.Phread = int64(n.phread) + c.Phwrite = int64(n.phwrite) + c.Iget = int64(n.iget) + c.Namei = int64(n.namei) + c.Dirblk = int64(n.dirblk) + c.Msg = int64(n.msg) + c.Sema = int64(n.sema) + c.MinFaults = int64(n.minfaults) + c.MajFaults = int64(n.majfaults) + c.PUser = int64(n.puser) + c.PSys = int64(n.psys) + c.PIdle = int64(n.pidle) + c.PWait = int64(n.pwait) + c.RedispSD0 = int64(n.redisp_sd0) + c.RedispSD1 = int64(n.redisp_sd1) + c.RedispSD2 = int64(n.redisp_sd2) + c.RedispSD3 = int64(n.redisp_sd3) + c.RedispSD4 = int64(n.redisp_sd4) + c.RedispSD5 = int64(n.redisp_sd5) + c.MigrationPush = int64(n.migration_push) + c.MigrationS3grq = int64(n.migration_S3grq) + c.MigrationS3pul = int64(n.migration_S3pul) + c.InvolCSwitch = int64(n.invol_cswitch) + c.VolCSwitch = int64(n.vol_cswitch) + c.RunQueue = int64(n.runque) + c.Bound = int64(n.bound) + c.DecrIntrs = int64(n.decrintrs) + c.MpcRIntrs = int64(n.mpcrintrs) + c.MpcSIntrs = int64(n.mpcsintrs) + c.SoftIntrs = int64(n.softintrs) + c.DevIntrs = int64(n.devintrs) + c.PhantIntrs = int64(n.phantintrs) + c.IdleDonatedPurr = int64(n.idle_donated_purr) + c.IdleDonatedSpurr = int64(n.idle_donated_spurr) + c.BusyDonatedPurr = int64(n.busy_donated_purr) + c.BusyDonatedSpurr = int64(n.busy_donated_spurr) + c.IdleStolenPurr = int64(n.idle_stolen_purr) + c.IdleStolenSpurr = int64(n.idle_stolen_spurr) + c.BusyStolenPurr = int64(n.busy_stolen_purr) + c.BusyStolenSpurr = int64(n.busy_stolen_spurr) + c.Hpi = int64(n.hpi) + c.Hpit = int64(n.hpit) + c.PUserSpurr = int64(n.puser_spurr) + c.PSysSpurr = int64(n.psys_spurr) + c.PIdleSpurr = int64(n.pidle_spurr) + c.PWaitSpurr = int64(n.pwait_spurr) + c.SpurrFlag = int32(n.spurrflag) + c.LocalDispatch = int64(n.localdispatch) + c.NearDispatch = int64(n.neardispatch) + c.FarDispatch = int64(n.fardispatch) + c.CSwitches = int64(n.cswitches) + c.Version = int64(n.version) + c.TbLast = int64(n.tb_last) + c.State = int(n.state) + c.VtbLast = int64(n.vtb_last) + c.ICountLast = int64(n.icount_last) + return c +} + +func perfstatcputotal2cputotal(n *C.perfstat_cpu_total_t) CPUTotal { + var c CPUTotal + c.NCpus = int(n.ncpus) + c.NCpusCfg = int(n.ncpus_cfg) + c.Description = C.GoString(&n.description[0]) + c.ProcessorHz = int64(n.processorHZ) + c.User = int64(n.user) + c.Sys = int64(n.sys) + c.Idle = int64(n.idle) + c.Wait = int64(n.wait) + c.PSwitch = int64(n.pswitch) + c.Syscall = int64(n.syscall) + c.Sysread = int64(n.sysread) + c.Syswrite = int64(n.syswrite) + c.Sysfork = int64(n.sysfork) + c.Sysexec = int64(n.sysexec) + c.Readch = int64(n.readch) + c.Writech = int64(n.writech) + c.DevIntrs = int64(n.devintrs) + c.SoftIntrs = int64(n.softintrs) + c.Lbolt = int64(n.lbolt) + c.LoadAvg1 = (float32(n.loadavg[0]) / (1 << C.SBITS)) + c.LoadAvg5 = (float32(n.loadavg[1]) / (1 << C.SBITS)) + c.LoadAvg15 = (float32(n.loadavg[2]) / (1 << C.SBITS)) + c.RunQueue = int64(n.runque) + c.SwpQueue = int64(n.swpque) + c.Bread = int64(n.bread) + c.Bwrite = int64(n.bwrite) + c.Lread = int64(n.lread) + c.Lwrite = int64(n.lwrite) + c.Phread = int64(n.phread) + c.Phwrite = int64(n.phwrite) + c.RunOcc = int64(n.runocc) + c.SwpOcc = int64(n.swpocc) + c.Iget = int64(n.iget) + c.Namei = int64(n.namei) + c.Dirblk = int64(n.dirblk) + c.Msg = int64(n.msg) + c.Sema = int64(n.sema) + c.RcvInt = int64(n.rcvint) + c.XmtInt = int64(n.xmtint) + c.MdmInt = int64(n.mdmint) + c.TtyRawInch = int64(n.tty_rawinch) + c.TtyCanInch = int64(n.tty_caninch) + c.TtyRawOutch = int64(n.tty_rawoutch) + c.Ksched = int64(n.ksched) + c.Koverf = int64(n.koverf) + c.Kexit = int64(n.kexit) + c.Rbread = int64(n.rbread) + c.Rcread = int64(n.rcread) + c.Rbwrt = int64(n.rbwrt) + c.Rcwrt = int64(n.rcwrt) + c.Traps = int64(n.traps) + c.NCpusHigh = int64(n.ncpus_high) + c.PUser = int64(n.puser) + c.PSys = int64(n.psys) + c.PIdle = int64(n.pidle) + c.PWait = int64(n.pwait) + c.DecrIntrs = int64(n.decrintrs) + c.MpcRIntrs = int64(n.mpcrintrs) + c.MpcSIntrs = int64(n.mpcsintrs) + c.PhantIntrs = int64(n.phantintrs) + c.IdleDonatedPurr = int64(n.idle_donated_purr) + c.IdleDonatedSpurr = int64(n.idle_donated_spurr) + c.BusyDonatedPurr = int64(n.busy_donated_purr) + c.BusyDonatedSpurr = int64(n.busy_donated_spurr) + c.IdleStolenPurr = int64(n.idle_stolen_purr) + c.IdleStolenSpurr = int64(n.idle_stolen_spurr) + c.BusyStolenPurr = int64(n.busy_stolen_purr) + c.BusyStolenSpurr = int64(n.busy_stolen_spurr) + c.IOWait = int32(n.iowait) + c.PhysIO = int32(n.physio) + c.TWait = int64(n.twait) + c.Hpi = int64(n.hpi) + c.Hpit = int64(n.hpit) + c.PUserSpurr = int64(n.puser_spurr) + c.PSysSpurr = int64(n.psys_spurr) + c.PIdleSpurr = int64(n.pidle_spurr) + c.PWaitSpurr = int64(n.pwait_spurr) + c.SpurrFlag = int(n.spurrflag) + c.Version = int64(n.version) + c.TbLast = int64(n.tb_last) + c.PurrCoalescing = int64(n.purr_coalescing) + c.SpurrCoalescing = int64(n.spurr_coalescing) + return c +} + +func perfstatcpuutil2cpuutil(n *C.perfstat_cpu_util_t) CPUUtil { + var c CPUUtil + + c.Version = int64(n.version) + c.CpuID = C.GoString(&n.cpu_id[0]) + c.Entitlement = float32(n.entitlement) + c.UserPct = float32(n.user_pct) + c.KernPct = float32(n.kern_pct) + c.IdlePct = float32(n.idle_pct) + c.WaitPct = float32(n.wait_pct) + c.PhysicalBusy = float32(n.physical_busy) + c.PhysicalConsumed = float32(n.physical_consumed) + c.FreqPct = float32(n.freq_pct) + c.EntitlementPct = float32(n.entitlement_pct) + c.BusyPct = float32(n.busy_pct) + c.IdleDonatedPct = float32(n.idle_donated_pct) + c.BusyDonatedPct = float32(n.busy_donated_pct) + c.IdleStolenPct = float32(n.idle_stolen_pct) + c.BusyStolenPct = float32(n.busy_stolen_pct) + c.LUserPct = float32(n.l_user_pct) + c.LKernPct = float32(n.l_kern_pct) + c.LIdlePct = float32(n.l_idle_pct) + c.LWaitPct = float32(n.l_wait_pct) + c.DeltaTime = int64(n.delta_time) + + return c +} + +func perfstatdisktotal2disktotal(n C.perfstat_disk_total_t) DiskTotal { + var d DiskTotal + + d.Number = int32(n.number) + d.Size = int64(n.size) + d.Free = int64(n.free) + d.XRate = int64(n.xrate) + d.Xfers = int64(n.xfers) + d.Wblks = int64(n.wblks) + d.Rblks = int64(n.rblks) + d.Time = int64(n.time) + d.Version = int64(n.version) + d.Rserv = int64(n.rserv) + d.MinRserv = int64(n.min_rserv) + d.MaxRserv = int64(n.max_rserv) + d.RTimeOut = int64(n.rtimeout) + d.RFailed = int64(n.rfailed) + d.Wserv = int64(n.wserv) + d.MinWserv = int64(n.min_wserv) + d.MaxWserv = int64(n.max_wserv) + d.WTimeOut = int64(n.wtimeout) + d.WFailed = int64(n.wfailed) + d.WqDepth = int64(n.wq_depth) + d.WqTime = int64(n.wq_time) + d.WqMinTime = int64(n.wq_min_time) + d.WqMaxTime = int64(n.wq_max_time) + + return d +} + +func perfstatdiskadapter2diskadapter(n *C.perfstat_diskadapter_t) DiskAdapter { + var d DiskAdapter + + d.Name = C.GoString(&n.name[0]) + d.Description = C.GoString(&n.description[0]) + d.Number = int32(n.number) + d.Size = int64(n.size) + d.Free = int64(n.free) + d.XRate = int64(n.xrate) + d.Xfers = int64(n.xfers) + d.Rblks = int64(n.rblks) + d.Wblks = int64(n.wblks) + d.Time = int64(n.time) + d.Version = int64(n.version) + d.AdapterType = int64(n.adapter_type) + d.DkBSize = int64(n.dk_bsize) + d.DkRserv = int64(n.dk_rserv) + d.DkWserv = int64(n.dk_wserv) + d.MinRserv = int64(n.min_rserv) + d.MaxRserv = int64(n.max_rserv) + d.MinWserv = int64(n.min_wserv) + d.MaxWserv = int64(n.max_wserv) + d.WqDepth = int64(n.wq_depth) + d.WqSampled = int64(n.wq_sampled) + d.WqTime = int64(n.wq_time) + d.WqMinTime = int64(n.wq_min_time) + d.WqMaxTime = int64(n.wq_max_time) + d.QFull = int64(n.q_full) + d.QSampled = int64(n.q_sampled) + + return d +} + +func perfstatpartitionconfig2partitionconfig(n C.perfstat_partition_config_t) PartitionConfig { + var p PartitionConfig + p.Version = int64(n.version) + p.Name = C.GoString(&n.partitionname[0]) + p.Node = C.GoString(&n.nodename[0]) + p.Conf.SmtCapable = (n.conf[0] & (1 << 7)) > 0 + p.Conf.SmtEnabled = (n.conf[0] & (1 << 6)) > 0 + p.Conf.LparCapable = (n.conf[0] & (1 << 5)) > 0 + p.Conf.LparEnabled = (n.conf[0] & (1 << 4)) > 0 + p.Conf.SharedCapable = (n.conf[0] & (1 << 3)) > 0 + p.Conf.SharedEnabled = (n.conf[0] & (1 << 2)) > 0 + p.Conf.DLparCapable = (n.conf[0] & (1 << 1)) > 0 + p.Conf.Capped = (n.conf[0] & (1 << 0)) > 0 + p.Conf.Kernel64bit = (n.conf[1] & (1 << 7)) > 0 + p.Conf.PoolUtilAuthority = (n.conf[1] & (1 << 6)) > 0 + p.Conf.DonateCapable = (n.conf[1] & (1 << 5)) > 0 + p.Conf.DonateEnabled = (n.conf[1] & (1 << 4)) > 0 + p.Conf.AmsCapable = (n.conf[1] & (1 << 3)) > 0 + p.Conf.AmsEnabled = (n.conf[1] & (1 << 2)) > 0 + p.Conf.PowerSave = (n.conf[1] & (1 << 1)) > 0 + p.Conf.AmeEnabled = (n.conf[1] & (1 << 0)) > 0 + p.Conf.SharedExtended = (n.conf[2] & (1 << 7)) > 0 + p.Number = int32(n.partitionnum) + p.GroupID = int32(n.groupid) + p.ProcessorFamily = C.GoString(&n.processorFamily[0]) + p.ProcessorModel = C.GoString(&n.processorModel[0]) + p.MachineID = C.GoString(&n.machineID[0]) + p.ProcessorMhz = float64(C.get_partition_mhz(n)) + p.NumProcessors.Online = int64(n.numProcessors.online) + p.NumProcessors.Max = int64(n.numProcessors.max) + p.NumProcessors.Min = int64(n.numProcessors.min) + p.NumProcessors.Desired = int64(n.numProcessors.desired) + p.OSName = C.GoString(&n.OSName[0]) + p.OSVersion = C.GoString(&n.OSVersion[0]) + p.OSBuild = C.GoString(&n.OSBuild[0]) + p.LCpus = int32(n.lcpus) + p.SmtThreads = int32(n.smtthreads) + p.Drives = int32(n.drives) + p.NetworkAdapters = int32(n.nw_adapters) + p.CpuCap.Online = int64(n.cpucap.online) + p.CpuCap.Max = int64(n.cpucap.max) + p.CpuCap.Min = int64(n.cpucap.min) + p.CpuCap.Desired = int64(n.cpucap.desired) + p.Weightage = int32(n.cpucap_weightage) + p.EntCapacity = int32(n.entitled_proc_capacity) + p.VCpus.Online = int64(n.vcpus.online) + p.VCpus.Max = int64(n.vcpus.max) + p.VCpus.Min = int64(n.vcpus.min) + p.VCpus.Desired = int64(n.vcpus.desired) + p.PoolID = int32(n.processor_poolid) + p.ActiveCpusInPool = int32(n.activecpusinpool) + p.PoolWeightage = int32(n.cpupool_weightage) + p.SharedPCpu = int32(n.sharedpcpu) + p.MaxPoolCap = int32(n.maxpoolcap) + p.EntPoolCap = int32(n.entpoolcap) + p.Mem.Online = int64(n.mem.online) + p.Mem.Max = int64(n.mem.max) + p.Mem.Min = int64(n.mem.min) + p.Mem.Desired = int64(n.mem.desired) + p.MemWeightage = int32(n.mem_weightage) + p.TotalIOMemoryEntitlement = int64(n.totiomement) + p.MemPoolID = int32(n.mempoolid) + p.HyperPgSize = int64(n.hyperpgsize) + p.ExpMem.Online = int64(n.exp_mem.online) + p.ExpMem.Max = int64(n.exp_mem.max) + p.ExpMem.Min = int64(n.exp_mem.min) + p.ExpMem.Desired = int64(n.exp_mem.desired) + p.TargetMemExpFactor = int64(n.targetmemexpfactor) + p.TargetMemExpSize = int64(n.targetmemexpsize) + p.SubProcessorMode = int32(n.subprocessor_mode) + return p +} + +func perfstatmemorytotal2memorytotal(n C.perfstat_memory_total_t) MemoryTotal { + var m MemoryTotal + m.VirtualTotal = int64(n.virt_total) + m.RealTotal = int64(n.real_total) + m.RealFree = int64(n.real_free) + m.RealPinned = int64(n.real_pinned) + m.RealInUse = int64(n.real_inuse) + m.BadPages = int64(n.pgbad) + m.PageFaults = int64(n.pgexct) + m.PageIn = int64(n.pgins) + m.PageOut = int64(n.pgouts) + m.PgSpIn = int64(n.pgspins) + m.PgSpOut = int64(n.pgspouts) + m.Scans = int64(n.scans) + m.Cycles = int64(n.cycles) + m.PgSteals = int64(n.pgsteals) + m.NumPerm = int64(n.numperm) + m.PgSpTotal = int64(n.pgsp_total) + m.PgSpFree = int64(n.pgsp_free) + m.PgSpRsvd = int64(n.pgsp_rsvd) + m.RealSystem = int64(n.real_system) + m.RealUser = int64(n.real_user) + m.RealProcess = int64(n.real_process) + m.VirtualActive = int64(n.virt_active) + m.IOME = int64(n.iome) + m.IOMU = int64(n.iomu) + m.IOHWM = int64(n.iohwm) + m.PMem = int64(n.pmem) + m.CompressedTotal = int64(n.comprsd_total) + m.CompressedWSegPg = int64(n.comprsd_wseg_pgs) + m.CPgIn = int64(n.cpgins) + m.CPgOut = int64(n.cpgouts) + m.TrueSize = int64(n.true_size) + m.ExpandedMemory = int64(n.expanded_memory) + m.CompressedWSegSize = int64(n.comprsd_wseg_size) + m.TargetCPoolSize = int64(n.target_cpool_size) + m.MaxCPoolSize = int64(n.max_cpool_size) + m.MinUCPoolSize = int64(n.min_ucpool_size) + m.CPoolSize = int64(n.cpool_size) + m.UCPoolSize = int64(n.ucpool_size) + m.CPoolInUse = int64(n.cpool_inuse) + m.UCPoolInUse = int64(n.ucpool_inuse) + m.Version = int64(n.version) + m.RealAvailable = int64(n.real_avail) + m.BytesCoalesced = int64(n.bytes_coalesced) + m.BytesCoalescedMemPool = int64(n.bytes_coalesced_mempool) + + return m +} + +func perfstatnetinterfacetotal2netifacetotal(n C.perfstat_netinterface_total_t) NetIfaceTotal { + var i NetIfaceTotal + + i.Number = int32(n.number) + i.IPackets = int64(n.ipackets) + i.IBytes = int64(n.ibytes) + i.IErrors = int64(n.ierrors) + i.OPackets = int64(n.opackets) + i.OBytes = int64(n.obytes) + i.OErrors = int64(n.oerrors) + i.Collisions = int64(n.collisions) + i.XmitDrops = int64(n.xmitdrops) + i.Version = int64(n.version) + + return i +} + +func perfstatdisk2disk(n *C.perfstat_disk_t) Disk { + var d Disk + + d.Name = C.GoString(&n.name[0]) + d.Description = C.GoString(&n.description[0]) + d.VGName = C.GoString(&n.vgname[0]) + d.Size = int64(n.size) + d.Free = int64(n.free) + d.BSize = int64(n.bsize) + d.XRate = int64(n.xrate) + d.Xfers = int64(n.xfers) + d.Wblks = int64(n.wblks) + d.Rblks = int64(n.rblks) + d.QDepth = int64(n.qdepth) + d.Time = int64(n.time) + d.Adapter = C.GoString(&n.adapter[0]) + d.PathsCount = int32(n.paths_count) + d.QFull = int64(n.q_full) + d.Rserv = int64(n.rserv) + d.RTimeOut = int64(n.rtimeout) + d.Rfailed = int64(n.rfailed) + d.MinRserv = int64(n.min_rserv) + d.MaxRserv = int64(n.max_rserv) + d.Wserv = int64(n.wserv) + d.WTimeOut = int64(n.wtimeout) + d.Wfailed = int64(n.wfailed) + d.MinWserv = int64(n.min_wserv) + d.MaxWserv = int64(n.max_wserv) + d.WqDepth = int64(n.wq_depth) + d.WqSampled = int64(n.wq_sampled) + d.WqTime = int64(n.wq_time) + d.WqMinTime = int64(n.wq_min_time) + d.WqMaxTime = int64(n.wq_max_time) + d.QSampled = int64(n.q_sampled) + d.Version = int64(n.version) + d.PseudoDisk = (n.dk_type[0] & (1 << 7)) > 0 + d.VTDisk = (n.dk_type[0] & (1 << 6)) > 0 + + return d +} + +func perfstatdiskpath2diskpath(n *C.perfstat_diskpath_t) DiskPath { + var d DiskPath + + d.Name = C.GoString(&n.name[0]) + d.XRate = int64(n.xrate) + d.Xfers = int64(n.xfers) + d.Rblks = int64(n.rblks) + d.Wblks = int64(n.wblks) + d.Time = int64(n.time) + d.Adapter = C.GoString(&n.adapter[0]) + d.QFull = int64(n.q_full) + d.Rserv = int64(n.rserv) + d.RTimeOut = int64(n.rtimeout) + d.Rfailed = int64(n.rfailed) + d.MinRserv = int64(n.min_rserv) + d.MaxRserv = int64(n.max_rserv) + d.Wserv = int64(n.wserv) + d.WTimeOut = int64(n.wtimeout) + d.Wfailed = int64(n.wfailed) + d.MinWserv = int64(n.min_wserv) + d.MaxWserv = int64(n.max_wserv) + d.WqDepth = int64(n.wq_depth) + d.WqSampled = int64(n.wq_sampled) + d.WqTime = int64(n.wq_time) + d.WqMinTime = int64(n.wq_min_time) + d.WqMaxTime = int64(n.wq_max_time) + d.QSampled = int64(n.q_sampled) + d.Version = int64(n.version) + + return d +} + +func perfstatfcstat2fcadapter(n *C.perfstat_fcstat_t) FCAdapter { + var f FCAdapter + + f.Version = int64(n.version) + f.Name = C.GoString(&n.name[0]) + f.State = int32(n.state) + f.InputRequests = int64(n.InputRequests) + f.OutputRequests = int64(n.OutputRequests) + f.InputBytes = int64(n.InputBytes) + f.OutputBytes = int64(n.OutputBytes) + f.EffMaxTransfer = int64(n.EffMaxTransfer) + f.NoDMAResourceCnt = int64(n.NoDMAResourceCnt) + f.NoCmdResourceCnt = int64(n.NoCmdResourceCnt) + f.AttentionType = int32(n.AttentionType) + f.SecondsSinceLastReset = int64(n.SecondsSinceLastReset) + f.TxFrames = int64(n.TxFrames) + f.TxWords = int64(n.TxWords) + f.RxFrames = int64(n.RxFrames) + f.RxWords = int64(n.RxWords) + f.LIPCount = int64(n.LIPCount) + f.NOSCount = int64(n.NOSCount) + f.ErrorFrames = int64(n.ErrorFrames) + f.DumpedFrames = int64(n.DumpedFrames) + f.LinkFailureCount = int64(n.LinkFailureCount) + f.LossofSyncCount = int64(n.LossofSyncCount) + f.LossofSignal = int64(n.LossofSignal) + f.PrimitiveSeqProtocolErrCount = int64(n.PrimitiveSeqProtocolErrCount) + f.InvalidTxWordCount = int64(n.InvalidTxWordCount) + f.InvalidCRCCount = int64(n.InvalidCRCCount) + f.PortFcId = int64(n.PortFcId) + f.PortSpeed = int64(n.PortSpeed) + f.PortType = C.GoString(&n.PortType[0]) + f.PortWWN = int64(n.PortWWN) + f.PortSupportedSpeed = int64(n.PortSupportedSpeed) + f.AdapterType = int(n.adapter_type) + f.VfcName = C.GoString(&n.vfc_name[0]) + f.ClientPartName = C.GoString(&n.client_part_name[0]) + + return f +} + +func perfstatlogicalvolume2logicalvolume(n *C.perfstat_logicalvolume_t) LogicalVolume { + var l LogicalVolume + + l.Name = C.GoString(&n.name[0]) + l.VGName = C.GoString(&n.vgname[0]) + l.OpenClose = int64(n.open_close) + l.State = int64(n.state) + l.MirrorPolicy = int64(n.mirror_policy) + l.MirrorWriteConsistency = int64(n.mirror_write_consistency) + l.WriteVerify = int64(n.write_verify) + l.PPsize = int64(n.ppsize) + l.LogicalPartitions = int64(n.logical_partitions) + l.Mirrors = int32(n.mirrors) + l.IOCnt = int64(n.iocnt) + l.KBReads = int64(n.kbreads) + l.KBWrites = int64(n.kbwrites) + l.Version = int64(n.version) + + return l +} + +func perfstatvolumegroup2volumegroup(n *C.perfstat_volumegroup_t) VolumeGroup { + var v VolumeGroup + + v.Name = C.GoString(&n.name[0]) + v.TotalDisks = int64(n.total_disks) + v.ActiveDisks = int64(n.active_disks) + v.TotalLogicalVolumes = int64(n.total_logical_volumes) + v.OpenedLogicalVolumes = int64(n.opened_logical_volumes) + v.IOCnt = int64(n.iocnt) + v.KBReads = int64(n.kbreads) + v.KBWrites = int64(n.kbwrites) + v.Version = int64(n.version) + v.VariedState = int(n.variedState) + + return v +} + +func perfstatmemorypage2memorypage(n *C.perfstat_memory_page_t) MemoryPage { + var m MemoryPage + + m.PSize = int64(n.psize) + m.RealTotal = int64(n.real_total) + m.RealFree = int64(n.real_free) + m.RealPinned = int64(n.real_pinned) + m.RealInUse = int64(n.real_inuse) + m.PgExct = int64(n.pgexct) + m.PgIns = int64(n.pgins) + m.PgOuts = int64(n.pgouts) + m.PgSpIns = int64(n.pgspins) + m.PgSpOuts = int64(n.pgspouts) + m.Scans = int64(n.scans) + m.Cycles = int64(n.cycles) + m.PgSteals = int64(n.pgsteals) + m.NumPerm = int64(n.numperm) + m.NumPgSp = int64(n.numpgsp) + m.RealSystem = int64(n.real_system) + m.RealUser = int64(n.real_user) + m.RealProcess = int64(n.real_process) + m.VirtActive = int64(n.virt_active) + m.ComprsdTotal = int64(n.comprsd_total) + m.ComprsdWsegPgs = int64(n.comprsd_wseg_pgs) + m.CPgIns = int64(n.cpgins) + m.CPgOuts = int64(n.cpgouts) + m.CPoolInUse = int64(n.cpool_inuse) + m.UCPoolSize = int64(n.ucpool_size) + m.ComprsdWsegSize = int64(n.comprsd_wseg_size) + m.Version = int64(n.version) + m.RealAvail = int64(n.real_avail) + + return m +} + +func perfstatnetbuffer2netbuffer(n *C.perfstat_netbuffer_t) NetBuffer { + var b NetBuffer + + b.Name = C.GoString(&n.name[0]) + b.InUse = int64(n.inuse) + b.Calls = int64(n.calls) + b.Delayed = int64(n.delayed) + b.Free = int64(n.free) + b.Failed = int64(n.failed) + b.HighWatermark = int64(n.highwatermark) + b.Freed = int64(n.freed) + b.Version = int64(n.version) + + return b +} + +func perfstatnetinterface2netiface(n *C.perfstat_netinterface_t) NetIface { + var i NetIface + + i.Name = C.GoString(&n.name[0]) + i.Description = C.GoString(&n.description[0]) + i.Type = uint8(n._type) + i.MTU = int64(n.mtu) + i.IPackets = int64(n.ipackets) + i.IBytes = int64(n.ibytes) + i.IErrors = int64(n.ierrors) + i.OPackets = int64(n.opackets) + i.OBytes = int64(n.obytes) + i.OErrors = int64(n.oerrors) + i.Collisions = int64(n.collisions) + i.Bitrate = int64(n.bitrate) + i.XmitDrops = int64(n.xmitdrops) + i.Version = int64(n.version) + i.IfIqDrops = int64(n.if_iqdrops) + i.IfArpDrops = int64(n.if_arpdrops) + + return i +} + +func perfstatnetadapter2netadapter(n *C.perfstat_netadapter_t) NetAdapter { + var i NetAdapter + + i.Version = int64(n.version) + i.Name = C.GoString(&n.name[0]) + i.TxPackets = int64(n.tx_packets) + i.TxBytes = int64(n.tx_bytes) + i.TxInterrupts = int64(n.tx_interrupts) + i.TxErrors = int64(n.tx_errors) + i.TxPacketsDropped = int64(n.tx_packets_dropped) + i.TxQueueSize = int64(n.tx_queue_size) + i.TxQueueLen = int64(n.tx_queue_len) + i.TxQueueOverflow = int64(n.tx_queue_overflow) + i.TxBroadcastPackets = int64(n.tx_broadcast_packets) + i.TxMulticastPackets = int64(n.tx_multicast_packets) + i.TxCarrierSense = int64(n.tx_carrier_sense) + i.TxDMAUnderrun = int64(n.tx_DMA_underrun) + i.TxLostCTSErrors = int64(n.tx_lost_CTS_errors) + i.TxMaxCollisionErrors = int64(n.tx_max_collision_errors) + i.TxLateCollisionErrors = int64(n.tx_late_collision_errors) + i.TxDeferred = int64(n.tx_deferred) + i.TxTimeoutErrors = int64(n.tx_timeout_errors) + i.TxSingleCollisionCount = int64(n.tx_single_collision_count) + i.TxMultipleCollisionCount = int64(n.tx_multiple_collision_count) + i.RxPackets = int64(n.rx_packets) + i.RxBytes = int64(n.rx_bytes) + i.RxInterrupts = int64(n.rx_interrupts) + i.RxErrors = int64(n.rx_errors) + i.RxPacketsDropped = int64(n.rx_packets_dropped) + i.RxBadPackets = int64(n.rx_bad_packets) + i.RxMulticastPackets = int64(n.rx_multicast_packets) + i.RxBroadcastPackets = int64(n.rx_broadcast_packets) + i.RxCRCErrors = int64(n.rx_CRC_errors) + i.RxDMAOverrun = int64(n.rx_DMA_overrun) + i.RxAlignmentErrors = int64(n.rx_alignment_errors) + i.RxNoResourceErrors = int64(n.rx_noresource_errors) + i.RxCollisionErrors = int64(n.rx_collision_errors) + i.RxPacketTooShortErrors = int64(n.rx_packet_tooshort_errors) + i.RxPacketTooLongErrors = int64(n.rx_packet_toolong_errors) + i.RxPacketDiscardedByAdapter = int64(n.rx_packets_discardedbyadapter) + i.AdapterType = int32(n.adapter_type) + + return i +} + +func perfstatpagingspace2pagingspace(n *C.perfstat_pagingspace_t) PagingSpace { + var i PagingSpace + + i.Name = C.GoString(&n.name[0]) + i.Type = uint8(n._type) + i.VGName = C.GoString(C.get_ps_vgname(n)) + i.Hostname = C.GoString(C.get_ps_hostname(n)) + i.Filename = C.GoString(C.get_ps_filename(n)) + i.LPSize = int64(n.lp_size) + i.MBSize = int64(n.mb_size) + i.MBUsed = int64(n.mb_used) + i.IOPending = int64(n.io_pending) + i.Active = uint8(n.active) + i.Automatic = uint8(n.automatic) + i.Version = int64(n.version) + + return i +} + +func perfstatprocess2process(n *C.perfstat_process_t) Process { + var i Process + + i.Version = int64(n.version) + i.PID = int64(n.pid) + i.ProcessName = C.GoString(&n.proc_name[0]) + i.Priority = int32(n.proc_priority) + i.NumThreads = int64(n.num_threads) + i.UID = int64(n.proc_uid) + i.ClassID = int64(n.proc_classid) + i.Size = int64(n.proc_size) + i.RealMemData = int64(n.proc_real_mem_data) + i.RealMemText = int64(n.proc_real_mem_text) + i.VirtMemData = int64(n.proc_virt_mem_data) + i.VirtMemText = int64(n.proc_virt_mem_text) + i.SharedLibDataSize = int64(n.shared_lib_data_size) + i.HeapSize = int64(n.heap_size) + i.RealInUse = int64(n.real_inuse) + i.VirtInUse = int64(n.virt_inuse) + i.Pinned = int64(n.pinned) + i.PgSpInUse = int64(n.pgsp_inuse) + i.FilePages = int64(n.filepages) + i.RealInUseMap = int64(n.real_inuse_map) + i.VirtInUseMap = int64(n.virt_inuse_map) + i.PinnedInUseMap = int64(n.pinned_inuse_map) + i.UCpuTime = float64(n.ucpu_time) + i.SCpuTime = float64(n.scpu_time) + i.LastTimeBase = int64(n.last_timebase) + i.InBytes = int64(n.inBytes) + i.OutBytes = int64(n.outBytes) + i.InOps = int64(n.inOps) + i.OutOps = int64(n.outOps) + + return i +} + +func perfstatthread2thread(n *C.perfstat_thread_t) Thread { + var i Thread + + i.TID = int64(n.tid) + i.PID = int64(n.pid) + i.CpuID = int64(n.cpuid) + i.UCpuTime = float64(n.ucpu_time) + i.SCpuTime = float64(n.scpu_time) + i.LastTimeBase = int64(n.last_timebase) + i.Version = int64(n.version) + + return i +} + +func fsinfo2filesystem(n *C.struct_fsinfo) FileSystem { + var i FileSystem + + i.Device = C.GoString(n.devname) + i.MountPoint = C.GoString(n.fsname) + i.FSType = int(n.fstype) + i.Flags = int(n.flags) + i.TotalBlocks = int64(n.totalblks) + i.FreeBlocks = int64(n.freeblks) + i.TotalInodes = int64(n.totalinodes) + i.FreeInodes = int64(n.freeinodes) + + return i +} diff --git a/vendor/github.com/power-devops/perfstat/lparstat.go b/vendor/github.com/power-devops/perfstat/lparstat.go new file mode 100644 index 0000000000..0ce35e3c56 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/lparstat.go @@ -0,0 +1,26 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +*/ +import "C" + +import ( + "fmt" +) + +func PartitionStat() (*PartitionConfig, error) { + var part C.perfstat_partition_config_t + + rc := C.perfstat_partition_config(nil, &part, C.sizeof_perfstat_partition_config_t, 1) + if rc != 1 { + return nil, fmt.Errorf("perfstat_partition_config() error") + } + p := perfstatpartitionconfig2partitionconfig(part) + return &p, nil + +} diff --git a/vendor/github.com/power-devops/perfstat/lvmstat.go b/vendor/github.com/power-devops/perfstat/lvmstat.go new file mode 100644 index 0000000000..eb2064c804 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/lvmstat.go @@ -0,0 +1,72 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +#include +#include +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" + "unsafe" +) + +func LogicalVolumeStat() ([]LogicalVolume, error) { + var lv *C.perfstat_logicalvolume_t + var lvname C.perfstat_id_t + + numlvs := C.perfstat_logicalvolume(nil, nil, C.sizeof_perfstat_logicalvolume_t, 0) + if numlvs <= 0 { + return nil, fmt.Errorf("perfstat_logicalvolume() error") + } + + lv_len := C.sizeof_perfstat_logicalvolume_t * C.ulong(numlvs) + lv = (*C.perfstat_logicalvolume_t)(C.malloc(lv_len)) + defer C.free(unsafe.Pointer(lv)) + C.strcpy(&lvname.name[0], C.CString("")) + r := C.perfstat_logicalvolume(&lvname, lv, C.sizeof_perfstat_logicalvolume_t, numlvs) + if r < 0 { + return nil, fmt.Errorf("perfstat_logicalvolume() error") + } + lvs := make([]LogicalVolume, r) + for i := 0; i < int(r); i++ { + l := C.get_logicalvolume_stat(lv, C.int(i)) + if l != nil { + lvs[i] = perfstatlogicalvolume2logicalvolume(l) + } + } + return lvs, nil +} + +func VolumeGroupStat() ([]VolumeGroup, error) { + var vg *C.perfstat_volumegroup_t + var vgname C.perfstat_id_t + + numvgs := C.perfstat_volumegroup(nil, nil, C.sizeof_perfstat_volumegroup_t, 0) + if numvgs <= 0 { + return nil, fmt.Errorf("perfstat_volumegroup() error") + } + + vg_len := C.sizeof_perfstat_volumegroup_t * C.ulong(numvgs) + vg = (*C.perfstat_volumegroup_t)(C.malloc(vg_len)) + defer C.free(unsafe.Pointer(vg)) + C.strcpy(&vgname.name[0], C.CString("")) + r := C.perfstat_volumegroup(&vgname, vg, C.sizeof_perfstat_volumegroup_t, numvgs) + if r < 0 { + return nil, fmt.Errorf("perfstat_volumegroup() error") + } + vgs := make([]VolumeGroup, r) + for i := 0; i < int(r); i++ { + v := C.get_volumegroup_stat(vg, C.int(i)) + if v != nil { + vgs[i] = perfstatvolumegroup2volumegroup(v) + } + } + return vgs, nil +} diff --git a/vendor/github.com/power-devops/perfstat/memstat.go b/vendor/github.com/power-devops/perfstat/memstat.go new file mode 100644 index 0000000000..d211a73aac --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/memstat.go @@ -0,0 +1,84 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +#include +#include + +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" + "unsafe" +) + +func MemoryTotalStat() (*MemoryTotal, error) { + var memory C.perfstat_memory_total_t + + rc := C.perfstat_memory_total(nil, &memory, C.sizeof_perfstat_memory_total_t, 1) + if rc != 1 { + return nil, fmt.Errorf("perfstat_memory_total() error") + } + m := perfstatmemorytotal2memorytotal(memory) + return &m, nil +} + +func MemoryPageStat() ([]MemoryPage, error) { + var mempage *C.perfstat_memory_page_t + var fps C.perfstat_psize_t + + numps := C.perfstat_memory_page(nil, nil, C.sizeof_perfstat_memory_page_t, 0) + if numps < 1 { + return nil, fmt.Errorf("perfstat_memory_page() error") + } + + mp_len := C.sizeof_perfstat_memory_page_t * C.ulong(numps) + mempage = (*C.perfstat_memory_page_t)(C.malloc(mp_len)) + defer C.free(unsafe.Pointer(mempage)) + fps.psize = C.FIRST_PSIZE + r := C.perfstat_memory_page(&fps, mempage, C.sizeof_perfstat_memory_page_t, numps) + if r < 1 { + return nil, fmt.Errorf("perfstat_memory_page() error") + } + ps := make([]MemoryPage, r) + for i := 0; i < int(r); i++ { + p := C.get_memory_page_stat(mempage, C.int(i)) + if p != nil { + ps[i] = perfstatmemorypage2memorypage(p) + } + } + return ps, nil +} + +func PagingSpaceStat() ([]PagingSpace, error) { + var pspace *C.perfstat_pagingspace_t + var fps C.perfstat_id_t + + numps := C.perfstat_pagingspace(nil, nil, C.sizeof_perfstat_pagingspace_t, 0) + if numps <= 0 { + return nil, fmt.Errorf("perfstat_pagingspace() error") + } + + ps_len := C.sizeof_perfstat_pagingspace_t * C.ulong(numps) + pspace = (*C.perfstat_pagingspace_t)(C.malloc(ps_len)) + defer C.free(unsafe.Pointer(pspace)) + C.strcpy(&fps.name[0], C.CString(C.FIRST_PAGINGSPACE)) + r := C.perfstat_pagingspace(&fps, pspace, C.sizeof_perfstat_pagingspace_t, numps) + if r < 1 { + return nil, fmt.Errorf("perfstat_pagingspace() error") + } + ps := make([]PagingSpace, r) + for i := 0; i < int(r); i++ { + p := C.get_pagingspace_stat(pspace, C.int(i)) + if p != nil { + ps[i] = perfstatpagingspace2pagingspace(p) + } + } + return ps, nil +} diff --git a/vendor/github.com/power-devops/perfstat/netstat.go b/vendor/github.com/power-devops/perfstat/netstat.go new file mode 100644 index 0000000000..4070da211b --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/netstat.go @@ -0,0 +1,117 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +#include +#include + +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" + "unsafe" +) + +func NetIfaceTotalStat() (*NetIfaceTotal, error) { + var nif C.perfstat_netinterface_total_t + + rc := C.perfstat_netinterface_total(nil, &nif, C.sizeof_perfstat_netinterface_total_t, 1) + if rc != 1 { + return nil, fmt.Errorf("perfstat_netinterface_total() error") + } + n := perfstatnetinterfacetotal2netifacetotal(nif) + return &n, nil +} + +func NetBufferStat() ([]NetBuffer, error) { + var nbuf *C.perfstat_netbuffer_t + var first C.perfstat_id_t + + numbuf := C.perfstat_netbuffer(nil, nil, C.sizeof_perfstat_netbuffer_t, 0) + if numbuf < 1 { + return nil, fmt.Errorf("perfstat_netbuffer() error") + } + + nblen := C.sizeof_perfstat_netbuffer_t * C.ulong(numbuf) + nbuf = (*C.perfstat_netbuffer_t)(C.malloc(nblen)) + defer C.free(unsafe.Pointer(nbuf)) + C.strcpy(&first.name[0], C.CString(C.FIRST_NETBUFFER)) + r := C.perfstat_netbuffer(&first, nbuf, C.sizeof_perfstat_netbuffer_t, numbuf) + if r < 0 { + return nil, fmt.Errorf("perfstat_netbuffer() error") + } + nb := make([]NetBuffer, r) + for i := 0; i < int(r); i++ { + b := C.get_netbuffer_stat(nbuf, C.int(i)) + if b != nil { + nb[i] = perfstatnetbuffer2netbuffer(b) + } + } + return nb, nil +} + +func NetIfaceStat() ([]NetIface, error) { + var nif *C.perfstat_netinterface_t + var first C.perfstat_id_t + + numif := C.perfstat_netinterface(nil, nil, C.sizeof_perfstat_netinterface_t, 0) + if numif < 0 { + return nil, fmt.Errorf("perfstat_netinterface() error") + } + if numif == 0 { + return []NetIface{}, fmt.Errorf("no network interfaces found") + } + + iflen := C.sizeof_perfstat_netinterface_t * C.ulong(numif) + nif = (*C.perfstat_netinterface_t)(C.malloc(iflen)) + defer C.free(unsafe.Pointer(nif)) + C.strcpy(&first.name[0], C.CString(C.FIRST_NETINTERFACE)) + r := C.perfstat_netinterface(&first, nif, C.sizeof_perfstat_netinterface_t, numif) + if r < 0 { + return nil, fmt.Errorf("perfstat_netinterface() error") + } + ifs := make([]NetIface, r) + for i := 0; i < int(r); i++ { + b := C.get_netinterface_stat(nif, C.int(i)) + if b != nil { + ifs[i] = perfstatnetinterface2netiface(b) + } + } + return ifs, nil +} + +func NetAdapterStat() ([]NetAdapter, error) { + var adapters *C.perfstat_netadapter_t + var first C.perfstat_id_t + + numad := C.perfstat_netadapter(nil, nil, C.sizeof_perfstat_netadapter_t, 0) + if numad < 0 { + return nil, fmt.Errorf("perfstat_netadater() error") + } + if numad == 0 { + return []NetAdapter{}, fmt.Errorf("no network adapters found") + } + + adplen := C.sizeof_perfstat_netadapter_t * C.ulong(numad) + adapters = (*C.perfstat_netadapter_t)(C.malloc(adplen)) + defer C.free(unsafe.Pointer(adapters)) + C.strcpy(&first.name[0], C.CString(C.FIRST_NETINTERFACE)) + r := C.perfstat_netadapter(&first, adapters, C.sizeof_perfstat_netadapter_t, numad) + if r < 0 { + return nil, fmt.Errorf("perfstat_netadapter() error") + } + ads := make([]NetAdapter, r) + for i := 0; i < int(r); i++ { + b := C.get_netadapter_stat(adapters, C.int(i)) + if b != nil { + ads[i] = perfstatnetadapter2netadapter(b) + } + } + return ads, nil +} diff --git a/vendor/github.com/power-devops/perfstat/procstat.go b/vendor/github.com/power-devops/perfstat/procstat.go new file mode 100644 index 0000000000..ecafebd8db --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/procstat.go @@ -0,0 +1,75 @@ +// +build aix + +package perfstat + +/* +#cgo LDFLAGS: -lperfstat + +#include +#include +#include + +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" + "unsafe" +) + +func ProcessStat() ([]Process, error) { + var proc *C.perfstat_process_t + var first C.perfstat_id_t + + numproc := C.perfstat_process(nil, nil, C.sizeof_perfstat_process_t, 0) + if numproc < 1 { + return nil, fmt.Errorf("perfstat_process() error") + } + + plen := C.sizeof_perfstat_process_t * C.ulong(numproc) + proc = (*C.perfstat_process_t)(C.malloc(plen)) + defer C.free(unsafe.Pointer(proc)) + C.strcpy(&first.name[0], C.CString("")) + r := C.perfstat_process(&first, proc, C.sizeof_perfstat_process_t, numproc) + if r < 0 { + return nil, fmt.Errorf("perfstat_process() error") + } + + ps := make([]Process, r) + for i := 0; i < int(r); i++ { + p := C.get_process_stat(proc, C.int(i)) + if p != nil { + ps[i] = perfstatprocess2process(p) + } + } + return ps, nil +} + +func ThreadStat() ([]Thread, error) { + var thread *C.perfstat_thread_t + var first C.perfstat_id_t + + numthr := C.perfstat_thread(nil, nil, C.sizeof_perfstat_thread_t, 0) + if numthr < 1 { + return nil, fmt.Errorf("perfstat_thread() error") + } + + thlen := C.sizeof_perfstat_thread_t * C.ulong(numthr) + thread = (*C.perfstat_thread_t)(C.malloc(thlen)) + defer C.free(unsafe.Pointer(thread)) + C.strcpy(&first.name[0], C.CString("")) + r := C.perfstat_thread(&first, thread, C.sizeof_perfstat_thread_t, numthr) + if r < 0 { + return nil, fmt.Errorf("perfstat_thread() error") + } + + th := make([]Thread, r) + for i := 0; i < int(r); i++ { + t := C.get_thread_stat(thread, C.int(i)) + if t != nil { + th[i] = perfstatthread2thread(t) + } + } + return th, nil +} diff --git a/vendor/github.com/power-devops/perfstat/sysconf.go b/vendor/github.com/power-devops/perfstat/sysconf.go new file mode 100644 index 0000000000..c7454d03d4 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/sysconf.go @@ -0,0 +1,195 @@ +// +build aix + +package perfstat + +/* +#include +*/ +import "C" + +import "fmt" + +const ( + SC_ARG_MAX = 0 + SC_CHILD_MAX = 1 + SC_CLK_TCK = 2 + SC_NGROUPS_MAX = 3 + SC_OPEN_MAX = 4 + SC_STREAM_MAX = 5 + SC_TZNAME_MAX = 6 + SC_JOB_CONTROL = 7 + SC_SAVED_IDS = 8 + SC_VERSION = 9 + SC_POSIX_ARG_MAX = 10 + SC_POSIX_CHILD_MAX = 11 + SC_POSIX_LINK_MAX = 12 + SC_POSIX_MAX_CANON = 13 + SC_POSIX_MAX_INPUT = 14 + SC_POSIX_NAME_MAX = 15 + SC_POSIX_NGROUPS_MAX = 16 + SC_POSIX_OPEN_MAX = 17 + SC_POSIX_PATH_MAX = 18 + SC_POSIX_PIPE_BUF = 19 + SC_POSIX_SSIZE_MAX = 20 + SC_POSIX_STREAM_MAX = 21 + SC_POSIX_TZNAME_MAX = 22 + SC_BC_BASE_MAX = 23 + SC_BC_DIM_MAX = 24 + SC_BC_SCALE_MAX = 25 + SC_BC_STRING_MAX = 26 + SC_EQUIV_CLASS_MAX = 27 + SC_EXPR_NEST_MAX = 28 + SC_LINE_MAX = 29 + SC_RE_DUP_MAX = 30 + SC_2_VERSION = 31 + SC_2_C_DEV = 32 + SC_2_FORT_DEV = 33 + SC_2_FORT_RUN = 34 + SC_2_LOCALEDEF = 35 + SC_2_SW_DEV = 36 + SC_POSIX2_BC_BASE_MAX = 37 + SC_POSIX2_BC_DIM_MAX = 38 + SC_POSIX2_BC_SCALE_MAX = 39 + SC_POSIX2_BC_STRING_MAX = 40 + SC_POSIX2_BC_EQUIV_CLASS_MAX = 41 + SC_POSIX2_BC_EXPR_NEST_MAX = 42 + SC_POSIX2_BC_LINE_MAX = 43 + SC_POSIX2_BC_RE_DUP_MAX = 44 + SC_PASS_MAX = 45 + SC_XOPEN_VERSION = 46 + SC_ATEXIT_MAX = 47 + SC_PAGE_SIZE = 48 + SC_PAGESIZE = SC_PAGE_SIZE + SC_AES_OS_VERSION = 49 + SC_COLL_WEIGHTS_MAX = 50 + SC_2_C_WIND = 51 + SC_2_C_VERSION = 52 + SC_2_UPE = 53 + SC_2_CHAR_TERM = 54 + SC_XOPEN_SHM = 55 + SC_XOPEN_CRYPT = 56 + SC_XOPEN_ENH_I18N = 57 + SC_IOV_MAX = 58 + SC_THREAD_SAFE_FUNCTIONS = 59 + SC_THREADS = 60 + SC_THREAD_ATTR_STACKADDR = 61 + SC_THREAD_ATTR_STACKSIZE = 62 + SC_THREAD_FORKALL = 63 + SC_THREAD_PRIORITY_SCHEDULING = 64 + SC_THREAD_PRIO_INHERIT = 65 + SC_THREAD_PRIO_PROTECT = 66 + SC_THREAD_PROCESS_SHARED = 67 + SC_THREAD_KEYS_MAX = 68 + SC_THREAD_DATAKEYS_MAX = SC_THREAD_KEYS_MAX + SC_THREAD_STACK_MIN = 69 + SC_THREAD_THREADS_MAX = 70 + SC_NPROCESSORS_CONF = 71 + SC_NPROCESSORS_ONLN = 72 + SC_XOPEN_UNIX = 73 + SC_AIO_LISTIO_MAX = 75 + SC_AIO_MAX = 76 + SC_AIO_PRIO_DELTA_MAX = 77 + SC_ASYNCHRONOUS_IO = 78 + SC_DELAYTIMER_MAX = 79 + SC_FSYNC = 80 + SC_GETGR_R_SIZE_MAX = 81 + SC_GETPW_R_SIZE_MAX = 82 + SC_LOGIN_NAME_MAX = 83 + SC_MAPPED_FILES = 84 + SC_MEMLOCK = 85 + SC_MEMLOCK_RANGE = 86 + SC_MEMORY_PROTECTION = 87 + SC_MESSAGE_PASSING = 88 + SC_MQ_OPEN_MAX = 89 + SC_MQ_PRIO_MAX = 90 + SC_PRIORITIZED_IO = 91 + SC_PRIORITY_SCHEDULING = 92 + SC_REALTIME_SIGNALS = 93 + SC_RTSIG_MAX = 94 + SC_SEMAPHORES = 95 + SC_SEM_NSEMS_MAX = 96 + SC_SEM_VALUE_MAX = 97 + SC_SHARED_MEMORY_OBJECTS = 98 + SC_SIGQUEUE_MAX = 99 + SC_SYNCHRONIZED_IO = 100 + SC_THREAD_DESTRUCTOR_ITERATIONS = 101 + SC_TIMERS = 102 + SC_TIMER_MAX = 103 + SC_TTY_NAME_MAX = 104 + SC_XBS5_ILP32_OFF32 = 105 + SC_XBS5_ILP32_OFFBIG = 106 + SC_XBS5_LP64_OFF64 = 107 + SC_XBS5_LPBIG_OFFBIG = 108 + SC_XOPEN_XCU_VERSION = 109 + SC_XOPEN_REALTIME = 110 + SC_XOPEN_REALTIME_THREADS = 111 + SC_XOPEN_LEGACY = 112 + SC_REENTRANT_FUNCTIONS = SC_THREAD_SAFE_FUNCTIONS + SC_PHYS_PAGES = 113 + SC_AVPHYS_PAGES = 114 + SC_LPAR_ENABLED = 115 + SC_LARGE_PAGESIZE = 116 + SC_AIX_KERNEL_BITMODE = 117 + SC_AIX_REALMEM = 118 + SC_AIX_HARDWARE_BITMODE = 119 + SC_AIX_MP_CAPABLE = 120 + SC_V6_ILP32_OFF32 = 121 + SC_V6_ILP32_OFFBIG = 122 + SC_V6_LP64_OFF64 = 123 + SC_V6_LPBIG_OFFBIG = 124 + SC_XOPEN_STREAMS = 125 + SC_HOST_NAME_MAX = 126 + SC_REGEXP = 127 + SC_SHELL = 128 + SC_SYMLOOP_MAX = 129 + SC_ADVISORY_INFO = 130 + SC_FILE_LOCKING = 131 + SC_2_PBS = 132 + SC_2_PBS_ACCOUNTING = 133 + SC_2_PBS_CHECKPOINT = 134 + SC_2_PBS_LOCATE = 135 + SC_2_PBS_MESSAGE = 136 + SC_2_PBS_TRACK = 137 + SC_BARRIERS = 138 + SC_CLOCK_SELECTION = 139 + SC_CPUTIME = 140 + SC_MONOTONIC_CLOCK = 141 + SC_READER_WRITER_LOCKS = 142 + SC_SPAWN = 143 + SC_SPIN_LOCKS = 144 + SC_SPORADIC_SERVER = 145 + SC_THREAD_CPUTIME = 146 + SC_THREAD_SPORADIC_SERVER = 147 + SC_TIMEOUTS = 148 + SC_TRACE = 149 + SC_TRACE_EVENT_FILTER = 150 + SC_TRACE_INHERIT = 151 + SC_TRACE_LOG = 152 + SC_TYPED_MEMORY_OBJECTS = 153 + SC_IPV6 = 154 + SC_RAW_SOCKETS = 155 + SC_SS_REPL_MAX = 156 + SC_TRACE_EVENT_NAME_MAX = 157 + SC_TRACE_NAME_MAX = 158 + SC_TRACE_SYS_MAX = 159 + SC_TRACE_USER_EVENT_MAX = 160 + SC_AIX_UKEYS = 161 + SC_AIX_ENHANCED_AFFINITY = 162 + SC_V7_ILP32_OFF32 = 163 + SC_V7_ILP32_OFFBIG = 164 + SC_V7_LP64_OFF64 = 165 + SC_V7_LPBIG_OFFBIG = 166 + SC_THREAD_ROBUST_PRIO_INHERIT = 167 + SC_THREAD_ROBUST_PRIO_PROTECT = 168 + SC_XOPEN_UUCP = 169 + SC_XOPEN_ARMOR = 170 +) + +func Sysconf(name int32) (int64, error) { + r := C.sysconf(C.int(name)) + if r == -1 { + return 0, fmt.Errorf("sysconf error") + } else { + return int64(r), nil + } +} diff --git a/vendor/github.com/power-devops/perfstat/systemcfg.go b/vendor/github.com/power-devops/perfstat/systemcfg.go new file mode 100644 index 0000000000..6287eb46ab --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/systemcfg.go @@ -0,0 +1,635 @@ +// +build aix + +package perfstat + +import "golang.org/x/sys/unix" + +// function Getsystemcfg() is defined in golang.org/x/sys/unix +// we define here just missing constants for the function and some helpers + +// Calls to getsystemcfg() +const ( + SC_ARCH = 1 /* processor architecture */ + SC_IMPL = 2 /* processor implementation */ + SC_VERS = 3 /* processor version */ + SC_WIDTH = 4 /* width (32 || 64) */ + SC_NCPUS = 5 /* 1 = UP, n = n-way MP */ + SC_L1C_ATTR = 6 /* L1 cache attributes (bit flags) */ + SC_L1C_ISZ = 7 /* size of L1 instruction cache */ + SC_L1C_DSZ = 8 /* size of L1 data cache */ + SC_L1C_ICA = 9 /* L1 instruction cache associativity */ + SC_L1C_DCA = 10 /* L1 data cache associativity */ + SC_L1C_IBS = 11 /* L1 instruction cache block size */ + SC_L1C_DBS = 12 /* L1 data cache block size */ + SC_L1C_ILS = 13 /* L1 instruction cache line size */ + SC_L1C_DLS = 14 /* L1 data cache line size */ + SC_L2C_SZ = 15 /* size of L2 cache, 0 = No L2 cache */ + SC_L2C_AS = 16 /* L2 cache associativity */ + SC_TLB_ATTR = 17 /* TLB attributes (bit flags) */ + SC_ITLB_SZ = 18 /* entries in instruction TLB */ + SC_DTLB_SZ = 19 /* entries in data TLB */ + SC_ITLB_ATT = 20 /* instruction tlb associativity */ + SC_DTLB_ATT = 21 /* data tlb associativity */ + SC_RESRV_SZ = 22 /* size of reservation */ + SC_PRI_LC = 23 /* spin lock count in supevisor mode */ + SC_PRO_LC = 24 /* spin lock count in problem state */ + SC_RTC_TYPE = 25 /* RTC type */ + SC_VIRT_AL = 26 /* 1 if hardware aliasing is supported */ + SC_CAC_CONG = 27 /* number of page bits for cache synonym */ + SC_MOD_ARCH = 28 /* used by system for model determination */ + SC_MOD_IMPL = 29 /* used by system for model determination */ + SC_XINT = 30 /* used by system for time base conversion */ + SC_XFRAC = 31 /* used by system for time base conversion */ + SC_KRN_ATTR = 32 /* kernel attributes, see below */ + SC_PHYSMEM = 33 /* bytes of OS available memory */ + SC_SLB_ATTR = 34 /* SLB attributes */ + SC_SLB_SZ = 35 /* size of slb (0 = no slb) */ + SC_ORIG_NCPUS = 36 /* original number of CPUs */ + SC_MAX_NCPUS = 37 /* max cpus supported by this AIX image */ + SC_MAX_REALADDR = 38 /* max supported real memory address +1 */ + SC_ORIG_ENT_CAP = 39 /* configured entitled processor capacity at boot required by cross-partition LPAR tools. */ + SC_ENT_CAP = 40 /* entitled processor capacity */ + SC_DISP_WHE = 41 /* Dispatch wheel time period (TB units) */ + SC_CAPINC = 42 /* delta by which capacity can change */ + SC_VCAPW = 43 /* priority weight for idle capacity distribution */ + SC_SPLP_STAT = 44 /* State of SPLPAR enablement: 0x1 => 1=SPLPAR capable; 0=not, 0x2 => SPLPAR enabled 0=dedicated, 1=shared */ + SC_SMT_STAT = 45 /* State of SMT enablement: 0x1 = SMT Capable 0=no/1=yes, 0x2 = SMT Enabled 0=no/1=yes, 0x4 = SMT threads bound true 0=no/1=yes */ + SC_SMT_TC = 46 /* Number of SMT Threads per Physical CPU */ + SC_VMX_VER = 47 /* RPA defined VMX version: 0 = VMX not available or disabled, 1 = VMX capable, 2 = VMX and VSX capable */ + SC_LMB_SZ = 48 /* Size of an LMB on this system. */ + SC_MAX_XCPU = 49 /* Number of exclusive cpus on line */ + SC_EC_LVL = 50 /* Kernel error checking level */ + SC_AME_STAT = 51 /* AME status */ + SC_ECO_STAT = 52 /* extended cache options */ + SC_DFP_STAT = 53 /* RPA defined DFP version, 0=none/disabled */ + SC_VRM_STAT = 54 /* VRM Capable/enabled */ + SC_PHYS_IMP = 55 /* physical processor implementation */ + SC_PHYS_VER = 56 /* physical processor version */ + SC_SPCM_STATUS = 57 + SC_SPCM_MAX = 58 + SC_TM_VER = 59 /* Transaction Memory version, 0 - not capable */ + SC_NX_CAP = 60 /* NX GZIP capable */ + SC_PKS_STATE = 61 /* Platform KeyStore */ +) + +/* kernel attributes */ +/* bit 0/1 meaning */ +/* -----------------------------------------*/ +/* 31 32-bit kernel / 64-bit kernel */ +/* 30 non-LPAR / LPAR */ +/* 29 old 64bit ABI / 64bit Large ABI */ +/* 28 non-NUMA / NUMA */ +/* 27 UP / MP */ +/* 26 no DR CPU add / DR CPU add support */ +/* 25 no DR CPU rm / DR CPU rm support */ +/* 24 no DR MEM add / DR MEM add support */ +/* 23 no DR MEM rm / DR MEM rm support */ +/* 22 kernel keys disabled / enabled */ +/* 21 no recovery / recovery enabled */ +/* 20 non-MLS / MLS enabled */ +/* 19 enhanced affinity indicator */ +/* 18 non-vTPM / vTPM enabled */ +/* 17 non-VIOS / VIOS */ + +// Values for architecture field +const ( + ARCH_POWER_RS = 0x0001 /* Power Classic architecture */ + ARCH_POWER_PC = 0x0002 /* Power PC architecture */ + ARCH_IA64 = 0x0003 /* Intel IA64 architecture */ +) + +// Values for implementation field for POWER_PC Architectures +const ( + IMPL_POWER_RS1 = 0x00001 /* RS1 class CPU */ + IMPL_POWER_RSC = 0x00002 /* RSC class CPU */ + IMPL_POWER_RS2 = 0x00004 /* RS2 class CPU */ + IMPL_POWER_601 = 0x00008 /* 601 class CPU */ + IMPL_POWER_603 = 0x00020 /* 603 class CPU */ + IMPL_POWER_604 = 0x00010 /* 604 class CPU */ + IMPL_POWER_620 = 0x00040 /* 620 class CPU */ + IMPL_POWER_630 = 0x00080 /* 630 class CPU */ + IMPL_POWER_A35 = 0x00100 /* A35 class CPU */ + IMPL_POWER_RS64II = 0x0200 /* RS64-II class CPU */ + IMPL_POWER_RS64III = 0x0400 /* RS64-III class CPU */ + IMPL_POWER4 = 0x0800 /* 4 class CPU */ + IMPL_POWER_RS64IV = IMPL_POWER4 /* 4 class CPU */ + IMPL_POWER_MPC7450 = 0x1000 /* MPC7450 class CPU */ + IMPL_POWER5 = 0x2000 /* 5 class CPU */ + IMPL_POWER6 = 0x4000 /* 6 class CPU */ + IMPL_POWER7 = 0x8000 /* 7 class CPU */ + IMPL_POWER8 = 0x10000 /* 8 class CPU */ + IMPL_POWER9 = 0x20000 /* 9 class CPU */ +) + +// Values for implementation field for IA64 Architectures +const ( + IMPL_IA64_M1 = 0x0001 /* IA64 M1 class CPU (Itanium) */ + IMPL_IA64_M2 = 0x0002 /* IA64 M2 class CPU */ +) + +// Values for the version field +const ( + PV_601 = 0x010001 /* Power PC 601 */ + PV_601A = 0x010002 /* Power PC 601 */ + PV_603 = 0x060000 /* Power PC 603 */ + PV_604 = 0x050000 /* Power PC 604 */ + PV_620 = 0x070000 /* Power PC 620 */ + PV_630 = 0x080000 /* Power PC 630 */ + PV_A35 = 0x090000 /* Power PC A35 */ + PV_RS64II = 0x0A0000 /* Power PC RS64II */ + PV_RS64III = 0x0B0000 /* Power PC RS64III */ + PV_4 = 0x0C0000 /* Power PC 4 */ + PV_RS64IV = PV_4 /* Power PC 4 */ + PV_MPC7450 = 0x0D0000 /* Power PC MPC7450 */ + PV_4_2 = 0x0E0000 /* Power PC 4 */ + PV_4_3 = 0x0E0001 /* Power PC 4 */ + PV_5 = 0x0F0000 /* Power PC 5 */ + PV_5_2 = 0x0F0001 /* Power PC 5 */ + PV_5_3 = 0x0F0002 /* Power PC 5 */ + PV_6 = 0x100000 /* Power PC 6 */ + PV_6_1 = 0x100001 /* Power PC 6 DD1.x */ + PV_7 = 0x200000 /* Power PC 7 */ + PV_8 = 0x300000 /* Power PC 8 */ + PV_9 = 0x400000 /* Power PC 9 */ + PV_5_Compat = 0x0F8000 /* Power PC 5 */ + PV_6_Compat = 0x108000 /* Power PC 6 */ + PV_7_Compat = 0x208000 /* Power PC 7 */ + PV_8_Compat = 0x308000 /* Power PC 8 */ + PV_9_Compat = 0x408000 /* Power PC 9 */ + PV_RESERVED_2 = 0x0A0000 /* source compatability */ + PV_RESERVED_3 = 0x0B0000 /* source compatability */ + PV_RS2 = 0x040000 /* Power RS2 */ + PV_RS1 = 0x020000 /* Power RS1 */ + PV_RSC = 0x030000 /* Power RSC */ + PV_M1 = 0x008000 /* Intel IA64 M1 */ + PV_M2 = 0x008001 /* Intel IA64 M2 */ +) + +// Values for rtc_type +const ( + RTC_POWER = 1 /* rtc as defined by Power Arch. */ + RTC_POWER_PC = 2 /* rtc as defined by Power PC Arch. */ + RTC_IA64 = 3 /* rtc as defined by IA64 Arch. */ +) + +const NX_GZIP_PRESENT = 0x00000001 + +const ( + PKS_STATE_CAPABLE = 1 + PKS_STATE_ENABLED = 2 +) + +// Macros for identifying physical processor +const ( + PPI4_1 = 0x35 + PPI4_2 = 0x38 + PPI4_3 = 0x39 + PPI4_4 = 0x3C + PPI4_5 = 0x44 + PPI5_1 = 0x3A + PPI5_2 = 0x3B + PPI6_1 = 0x3E + PPI7_1 = 0x3F + PPI7_2 = 0x4A + PPI8_1 = 0x4B + PPI8_2 = 0x4D + PPI9 = 0x4E +) + +// Macros for kernel attributes +const ( + KERN_TYPE = 0x1 + KERN_LPAR = 0x2 + KERN_64BIT_LARGE_ABI = 0x4 + KERN_NUMA = 0x8 + KERN_UPMP = 0x10 + KERN_DR_CPU_ADD = 0x20 + KERN_DR_CPU_RM = 0x40 + KERN_DR_MEM_ADD = 0x80 + KERN_DR_MEM_RM = 0x100 + KERN_KKEY_ENABLED = 0x200 + KERN_RECOVERY = 0x400 + KERN_MLS = 0x800 + KERN_ENH_AFFINITY = 0x1000 + KERN_VTPM = 0x2000 + KERN_VIOS = 0x4000 +) + +// macros for SPLPAR environment. +const ( + SPLPAR_CAPABLE = 0x1 + SPLPAR_ENABLED = 0x2 + SPLPAR_DONATE_CAPABLE = 0x4 +) + +// Macros for SMT status determination +const ( + SMT_CAPABLE = 0x1 + SMT_ENABLE = 0x2 + SMT_BOUND = 0x4 + SMT_ORDER = 0x8 +) + +// Macros for VRM status determination +const ( + VRM_CAPABLE = 0x1 + VRM_ENABLE = 0x2 + CMOX_CAPABLE = 0x4 +) + +// Macros for AME status determination +const AME_ENABLE = 0x1 + +// Macros for extended cache options +const ( + ECO_CAPABLE = 0x1 + ECO_ENABLE = 0x2 +) + +// These define blocks of values for model_arch and model_impl that are reserved for OEM use. +const ( + MODEL_ARCH_RSPC = 2 + MODEL_ARCH_CHRP = 3 + MODEL_ARCH_IA64 = 4 + MODEL_ARCH_OEM_START = 1024 + MODEL_ARCH_OEM_END = 2047 + MODEL_IMPL_RS6K_UP_MCA = 1 + MODEL_IMPL_RS6K_SMP_MCA = 2 + MODEL_IMPL_RSPC_UP_PCI = 3 + MODEL_IMPL_RSPC_SMP_PCI = 4 + MODEL_IMPL_CHRP_UP_PCI = 5 + MODEL_IMPL_CHRP_SMP_PCI = 6 + MODEL_IMPL_IA64_COM = 7 + MODEL_IMPL_IA64_SOFTSDV = 8 + MODEL_IMPL_MAMBO_SIM = 9 + MODEL_IMPL_POWER_KVM = 10 + MODEL_IMPL_OEM_START = 1024 + MODEL_IMPL_OEM_END = 2047 +) + +// example determining processor compatibilty mode on AIX: +// impl := unix.Getsystemcfg(SC_IMPL) +// if impl&IMPL_POWER8 != 0 { +// // we are running on POWER8 +// } +// if impl&IMPL_POWER9 != 0 { +// // we are running on POWER9 +// } + +func GetCPUImplementation() string { + impl := unix.Getsystemcfg(SC_IMPL) + switch { + case impl&IMPL_POWER4 != 0: + return "POWER4" + case impl&IMPL_POWER5 != 0: + return "POWER5" + case impl&IMPL_POWER6 != 0: + return "POWER6" + case impl&IMPL_POWER7 != 0: + return "POWER7" + case impl&IMPL_POWER8 != 0: + return "POWER8" + case impl&IMPL_POWER9 != 0: + return "POWER9" + default: + return "Unknown" + } +} + +func POWER9OrNewer() bool { + impl := unix.Getsystemcfg(SC_IMPL) + if impl&IMPL_POWER9 != 0 { + return true + } + return false +} + +func POWER9() bool { + impl := unix.Getsystemcfg(SC_IMPL) + if impl&IMPL_POWER9 != 0 { + return true + } + return false +} + +func POWER8OrNewer() bool { + impl := unix.Getsystemcfg(SC_IMPL) + if impl&IMPL_POWER9 != 0 || impl&IMPL_POWER8 != 0 { + return true + } + return false +} + +func POWER8() bool { + impl := unix.Getsystemcfg(SC_IMPL) + if impl&IMPL_POWER8 != 0 { + return true + } + return false +} + +func POWER7OrNewer() bool { + impl := unix.Getsystemcfg(SC_IMPL) + if impl&IMPL_POWER9 != 0 || impl&IMPL_POWER8 != 0 || impl&IMPL_POWER7 != 0 { + return true + } + return false +} + +func POWER7() bool { + impl := unix.Getsystemcfg(SC_IMPL) + if impl&IMPL_POWER7 != 0 { + return true + } + return false +} + +func HasTransactionalMemory() bool { + impl := unix.Getsystemcfg(SC_TM_VER) + if impl > 0 { + return true + } + return false +} + +func Is64Bit() bool { + impl := unix.Getsystemcfg(SC_WIDTH) + if impl == 64 { + return true + } + return false +} + +func IsSMP() bool { + impl := unix.Getsystemcfg(SC_NCPUS) + if impl > 1 { + return true + } + return false +} + +func HasVMX() bool { + impl := unix.Getsystemcfg(SC_VMX_VER) + if impl > 0 { + return true + } + return false +} + +func HasVSX() bool { + impl := unix.Getsystemcfg(SC_VMX_VER) + if impl > 1 { + return true + } + return false +} + +func HasDFP() bool { + impl := unix.Getsystemcfg(SC_DFP_STAT) + if impl > 1 { + return true + } + return false +} + +func HasNxGzip() bool { + impl := unix.Getsystemcfg(SC_NX_CAP) + if impl&NX_GZIP_PRESENT > 0 { + return true + } + return false +} + +func PksCapable() bool { + impl := unix.Getsystemcfg(SC_PKS_STATE) + if impl&PKS_STATE_CAPABLE > 0 { + return true + } + return false +} + +func PksEnabled() bool { + impl := unix.Getsystemcfg(SC_PKS_STATE) + if impl&PKS_STATE_ENABLED > 0 { + return true + } + return false +} + +func CPUMode() string { + impl := unix.Getsystemcfg(SC_VERS) + switch impl { + case PV_9, PV_9_Compat: + return "POWER9" + case PV_8, PV_8_Compat: + return "POWER8" + case PV_7, PV_7_Compat: + return "POWER7" + default: + return "Unknown" + } +} + +func KernelBits() int { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_TYPE == KERN_TYPE { + return 64 + } + return 32 +} + +func IsLPAR() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_LPAR == KERN_LPAR { + return true + } + return false +} + +func CpuAddCapable() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_DR_CPU_ADD == KERN_DR_CPU_ADD { + return true + } + return false +} + +func CpuRemoveCapable() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_DR_CPU_RM == KERN_DR_CPU_RM { + return true + } + return false +} + +func MemoryAddCapable() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_DR_MEM_ADD == KERN_DR_MEM_ADD { + return true + } + return false +} + +func MemoryRemoveCapable() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_DR_MEM_RM == KERN_DR_MEM_RM { + return true + } + return false +} + +func DLparCapable() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&(KERN_DR_CPU_ADD|KERN_DR_CPU_RM|KERN_DR_MEM_ADD|KERN_DR_MEM_RM) > 0 { + return true + } + return false +} + +func IsNUMA() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_NUMA > 0 { + return true + } + return false +} + +func KernelKeys() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_KKEY_ENABLED > 0 { + return true + } + return false +} + +func RecoveryMode() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_RECOVERY > 0 { + return true + } + return false +} + +func EnhancedAffinity() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_ENH_AFFINITY > 0 { + return true + } + return false +} + +func VTpmEnabled() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_VTPM > 0 { + return true + } + return false +} + +func IsVIOS() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_VIOS > 0 { + return true + } + return false +} + +func MLSEnabled() bool { + impl := unix.Getsystemcfg(SC_KRN_ATTR) + if impl&KERN_MLS > 0 { + return true + } + return false +} + +func SPLparCapable() bool { + impl := unix.Getsystemcfg(SC_SPLP_STAT) + if impl&SPLPAR_CAPABLE > 0 { + return true + } + return false +} + +func SPLparEnabled() bool { + impl := unix.Getsystemcfg(SC_SPLP_STAT) + if impl&SPLPAR_ENABLED > 0 { + return true + } + return false +} + +func DedicatedLpar() bool { + return !SPLparEnabled() +} + +func SPLparCapped() bool { + impl := unix.Getsystemcfg(SC_VCAPW) + if impl == 0 { + return true + } + return false +} + +func SPLparDonating() bool { + impl := unix.Getsystemcfg(SC_SPLP_STAT) + if impl&SPLPAR_DONATE_CAPABLE > 0 { + return true + } + return false +} + +func SmtCapable() bool { + impl := unix.Getsystemcfg(SC_SMT_STAT) + if impl&SMT_CAPABLE > 0 { + return true + } + return false +} + +func SmtEnabled() bool { + impl := unix.Getsystemcfg(SC_SMT_STAT) + if impl&SMT_ENABLE > 0 { + return true + } + return false +} + +func VrmCapable() bool { + impl := unix.Getsystemcfg(SC_VRM_STAT) + if impl&VRM_CAPABLE > 0 { + return true + } + return false +} + +func VrmEnabled() bool { + impl := unix.Getsystemcfg(SC_VRM_STAT) + if impl&VRM_ENABLE > 0 { + return true + } + return false +} + +func AmeEnabled() bool { + impl := unix.Getsystemcfg(SC_AME_STAT) + if impl&AME_ENABLE > 0 { + return true + } + return false +} + +func EcoCapable() bool { + impl := unix.Getsystemcfg(SC_ECO_STAT) + if impl&ECO_CAPABLE > 0 { + return true + } + return false +} + +func EcoEnabled() bool { + impl := unix.Getsystemcfg(SC_ECO_STAT) + if impl&ECO_ENABLE > 0 { + return true + } + return false +} diff --git a/vendor/github.com/power-devops/perfstat/types_cpu.go b/vendor/github.com/power-devops/perfstat/types_cpu.go new file mode 100644 index 0000000000..84425e92f5 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_cpu.go @@ -0,0 +1,186 @@ +package perfstat + +type CPU struct { + Name string /* logical processor name (cpu0, cpu1, ..) */ + User int64 /* raw number of clock ticks spent in user mode */ + Sys int64 /* raw number of clock ticks spent in system mode */ + Idle int64 /* raw number of clock ticks spent idle */ + Wait int64 /* raw number of clock ticks spent waiting for I/O */ + PSwitch int64 /* number of context switches (changes of currently running process) */ + Syscall int64 /* number of system calls executed */ + Sysread int64 /* number of read system calls executed */ + Syswrite int64 /* number of write system calls executed */ + Sysfork int64 /* number of fork system call executed */ + Sysexec int64 /* number of exec system call executed */ + Readch int64 /* number of characters tranferred with read system call */ + Writech int64 /* number of characters tranferred with write system call */ + Bread int64 /* number of block reads */ + Bwrite int64 /* number of block writes */ + Lread int64 /* number of logical read requests */ + Lwrite int64 /* number of logical write requests */ + Phread int64 /* number of physical reads (reads on raw device) */ + Phwrite int64 /* number of physical writes (writes on raw device) */ + Iget int64 /* number of inode lookups */ + Namei int64 /* number of vnode lookup from a path name */ + Dirblk int64 /* number of 512-byte block reads by the directory search routine to locate an entry for a file */ + Msg int64 /* number of IPC message operations */ + Sema int64 /* number of IPC semaphore operations */ + MinFaults int64 /* number of page faults with no I/O */ + MajFaults int64 /* number of page faults with disk I/O */ + PUser int64 /* raw number of physical processor tics in user mode */ + PSys int64 /* raw number of physical processor tics in system mode */ + PIdle int64 /* raw number of physical processor tics idle */ + PWait int64 /* raw number of physical processor tics waiting for I/O */ + RedispSD0 int64 /* number of thread redispatches within the scheduler affinity domain 0 */ + RedispSD1 int64 /* number of thread redispatches within the scheduler affinity domain 1 */ + RedispSD2 int64 /* number of thread redispatches within the scheduler affinity domain 2 */ + RedispSD3 int64 /* number of thread redispatches within the scheduler affinity domain 3 */ + RedispSD4 int64 /* number of thread redispatches within the scheduler affinity domain 4 */ + RedispSD5 int64 /* number of thread redispatches within the scheduler affinity domain 5 */ + MigrationPush int64 /* number of thread migrations from the local runque to another queue due to starvation load balancing */ + MigrationS3grq int64 /* number of thread migrations from the global runque to the local runque resulting in a move accross scheduling domain 3 */ + MigrationS3pul int64 /* number of thread migrations from another processor's runque resulting in a move accross scheduling domain 3 */ + InvolCSwitch int64 /* number of involuntary thread context switches */ + VolCSwitch int64 /* number of voluntary thread context switches */ + RunQueue int64 /* number of threads on the runque */ + Bound int64 /* number of bound threads */ + DecrIntrs int64 /* number of decrementer tics interrupts */ + MpcRIntrs int64 /* number of mpc's received interrupts */ + MpcSIntrs int64 /* number of mpc's sent interrupts */ + DevIntrs int64 /* number of device interrupts */ + SoftIntrs int64 /* number of offlevel handlers called */ + PhantIntrs int64 /* number of phantom interrupts */ + IdleDonatedPurr int64 /* number of idle cycles donated by a dedicated partition enabled for donation */ + IdleDonatedSpurr int64 /* number of idle spurr cycles donated by a dedicated partition enabled for donation */ + BusyDonatedPurr int64 /* number of busy cycles donated by a dedicated partition enabled for donation */ + BusyDonatedSpurr int64 /* number of busy spurr cycles donated by a dedicated partition enabled for donation */ + IdleStolenPurr int64 /* number of idle cycles stolen by the hypervisor from a dedicated partition */ + IdleStolenSpurr int64 /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */ + BusyStolenPurr int64 /* number of busy cycles stolen by the hypervisor from a dedicated partition */ + BusyStolenSpurr int64 /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */ + Hpi int64 /* number of hypervisor page-ins */ + Hpit int64 /* Time spent in hypervisor page-ins (in nanoseconds)*/ + PUserSpurr int64 /* number of spurr cycles spent in user mode */ + PSysSpurr int64 /* number of spurr cycles spent in kernel mode */ + PIdleSpurr int64 /* number of spurr cycles spent in idle mode */ + PWaitSpurr int64 /* number of spurr cycles spent in wait mode */ + SpurrFlag int32 /* set if running in spurr mode */ + LocalDispatch int64 /* number of local thread dispatches on this logical CPU */ + NearDispatch int64 /* number of near thread dispatches on this logical CPU */ + FarDispatch int64 /* number of far thread dispatches on this logical CPU */ + CSwitches int64 /* Context switches */ + Version int64 /* version number (1, 2, etc.,) */ + TbLast int64 /* timebase counter */ + State int /* Show whether the CPU is offline or online */ + VtbLast int64 /* Last virtual timebase read */ + ICountLast int64 /* Last instruction count read */ +} + +type CPUTotal struct { + NCpus int /* number of active logical processors */ + NCpusCfg int /* number of configured processors */ + Description string /* processor description (type/official name) */ + ProcessorHz int64 /* processor speed in Hz */ + User int64 /* raw total number of clock ticks spent in user mode */ + Sys int64 /* raw total number of clock ticks spent in system mode */ + Idle int64 /* raw total number of clock ticks spent idle */ + Wait int64 /* raw total number of clock ticks spent waiting for I/O */ + PSwitch int64 /* number of process switches (change in currently running process) */ + Syscall int64 /* number of system calls executed */ + Sysread int64 /* number of read system calls executed */ + Syswrite int64 /* number of write system calls executed */ + Sysfork int64 /* number of forks system calls executed */ + Sysexec int64 /* number of execs system calls executed */ + Readch int64 /* number of characters tranferred with read system call */ + Writech int64 /* number of characters tranferred with write system call */ + DevIntrs int64 /* number of device interrupts */ + SoftIntrs int64 /* number of software interrupts */ + Lbolt int64 /* number of ticks since last reboot */ + LoadAvg1 float32 /* times the average number of runnables processes during the last 1, 5 and 15 minutes. */ + LoadAvg5 float32 /* times the average number of runnables processes during the last 1, 5 and 15 minutes. */ + LoadAvg15 float32 /* times the average number of runnables processes during the last 1, 5 and 15 minutes. */ + RunQueue int64 /* length of the run queue (processes ready) */ + SwpQueue int64 /* length of the swap queue (processes waiting to be paged in) */ + Bread int64 /* number of blocks read */ + Bwrite int64 /* number of blocks written */ + Lread int64 /* number of logical read requests */ + Lwrite int64 /* number of logical write requests */ + Phread int64 /* number of physical reads (reads on raw devices) */ + Phwrite int64 /* number of physical writes (writes on raw devices) */ + RunOcc int64 /* updated whenever runque is updated, i.e. the runqueue is occupied. This can be used to compute the simple average of ready processes */ + SwpOcc int64 /* updated whenever swpque is updated. i.e. the swpqueue is occupied. This can be used to compute the simple average processes waiting to be paged in */ + Iget int64 /* number of inode lookups */ + Namei int64 /* number of vnode lookup from a path name */ + Dirblk int64 /* number of 512-byte block reads by the directory search routine to locate an entry for a file */ + Msg int64 /* number of IPC message operations */ + Sema int64 /* number of IPC semaphore operations */ + RcvInt int64 /* number of tty receive interrupts */ + XmtInt int64 /* number of tyy transmit interrupts */ + MdmInt int64 /* number of modem interrupts */ + TtyRawInch int64 /* number of raw input characters */ + TtyCanInch int64 /* number of canonical input characters (always zero) */ + TtyRawOutch int64 /* number of raw output characters */ + Ksched int64 /* number of kernel processes created */ + Koverf int64 /* kernel process creation attempts where: -the user has forked to their maximum limit -the configuration limit of processes has been reached */ + Kexit int64 /* number of kernel processes that became zombies */ + Rbread int64 /* number of remote read requests */ + Rcread int64 /* number of cached remote reads */ + Rbwrt int64 /* number of remote writes */ + Rcwrt int64 /* number of cached remote writes */ + Traps int64 /* number of traps */ + NCpusHigh int64 /* index of highest processor online */ + PUser int64 /* raw number of physical processor tics in user mode */ + PSys int64 /* raw number of physical processor tics in system mode */ + PIdle int64 /* raw number of physical processor tics idle */ + PWait int64 /* raw number of physical processor tics waiting for I/O */ + DecrIntrs int64 /* number of decrementer tics interrupts */ + MpcRIntrs int64 /* number of mpc's received interrupts */ + MpcSIntrs int64 /* number of mpc's sent interrupts */ + PhantIntrs int64 /* number of phantom interrupts */ + IdleDonatedPurr int64 /* number of idle cycles donated by a dedicated partition enabled for donation */ + IdleDonatedSpurr int64 /* number of idle spurr cycles donated by a dedicated partition enabled for donation */ + BusyDonatedPurr int64 /* number of busy cycles donated by a dedicated partition enabled for donation */ + BusyDonatedSpurr int64 /* number of busy spurr cycles donated by a dedicated partition enabled for donation */ + IdleStolenPurr int64 /* number of idle cycles stolen by the hypervisor from a dedicated partition */ + IdleStolenSpurr int64 /* number of idle spurr cycles stolen by the hypervisor from a dedicated partition */ + BusyStolenPurr int64 /* number of busy cycles stolen by the hypervisor from a dedicated partition */ + BusyStolenSpurr int64 /* number of busy spurr cycles stolen by the hypervisor from a dedicated partition */ + IOWait int32 /* number of processes that are asleep waiting for buffered I/O */ + PhysIO int32 /* number of processes waiting for raw I/O */ + TWait int64 /* number of threads that are waiting for filesystem direct(cio) */ + Hpi int64 /* number of hypervisor page-ins */ + Hpit int64 /* Time spent in hypervisor page-ins (in nanoseconds) */ + PUserSpurr int64 /* number of spurr cycles spent in user mode */ + PSysSpurr int64 /* number of spurr cycles spent in kernel mode */ + PIdleSpurr int64 /* number of spurr cycles spent in idle mode */ + PWaitSpurr int64 /* number of spurr cycles spent in wait mode */ + SpurrFlag int /* set if running in spurr mode */ + Version int64 /* version number (1, 2, etc.,) */ + TbLast int64 /*time base counter */ + PurrCoalescing int64 /* If the calling partition is authorized to see pool wide statistics then PURR cycles consumed to coalesce data else set to zero.*/ + SpurrCoalescing int64 /* If the calling partition is authorized to see pool wide statistics then SPURR cycles consumed to coalesce data else set to zero. */ +} + +type CPUUtil struct { + Version int64 + CpuID string /* holds the id of the cpu */ + Entitlement float32 /* Partition's entitlement */ + UserPct float32 /* % of utilization in user mode */ + KernPct float32 /* % of utilization in kernel mode */ + IdlePct float32 /* % of utilization in idle mode */ + WaitPct float32 /* % of utilization in wait mode */ + PhysicalBusy float32 /* physical cpus busy */ + PhysicalConsumed float32 /* total cpus consumed by the partition */ + FreqPct float32 /* Average freq% over the last interval */ + EntitlementPct float32 /* % of entitlement used */ + BusyPct float32 /* % of entitlement busy */ + IdleDonatedPct float32 /* % idle cycles donated */ + BusyDonatedPct float32 /* % of busy cycles donated */ + IdleStolenPct float32 /* % idle cycles stolen */ + BusyStolenPct float32 /* % busy cycles stolen */ + LUserPct float32 /* % of utilization in user mode, in terms of logical processor ticks */ + LKernPct float32 /* % of utilization in kernel mode, in terms of logical processor ticks*/ + LIdlePct float32 /* % of utilization in idle mode, in terms of logical processor ticks */ + LWaitPct float32 /* % of utilization in wait mode, in terms of logical processor ticks */ + DeltaTime int64 /* delta time in milliseconds, for which utilization is evaluated */ +} diff --git a/vendor/github.com/power-devops/perfstat/types_disk.go b/vendor/github.com/power-devops/perfstat/types_disk.go new file mode 100644 index 0000000000..ca1493d872 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_disk.go @@ -0,0 +1,176 @@ +package perfstat + +type DiskTotal struct { + Number int32 /* total number of disks */ + Size int64 /* total size of all disks (in MB) */ + Free int64 /* free portion of all disks (in MB) */ + XRate int64 /* __rxfers: total number of transfers from disk */ + Xfers int64 /* total number of transfers to/from disk */ + Wblks int64 /* 512 bytes blocks written to all disks */ + Rblks int64 /* 512 bytes blocks read from all disks */ + Time int64 /* amount of time disks are active */ + Version int64 /* version number (1, 2, etc.,) */ + Rserv int64 /* Average read or receive service time */ + MinRserv int64 /* min read or receive service time */ + MaxRserv int64 /* max read or receive service time */ + RTimeOut int64 /* number of read request timeouts */ + RFailed int64 /* number of failed read requests */ + Wserv int64 /* Average write or send service time */ + MinWserv int64 /* min write or send service time */ + MaxWserv int64 /* max write or send service time */ + WTimeOut int64 /* number of write request timeouts */ + WFailed int64 /* number of failed write requests */ + WqDepth int64 /* instantaneous wait queue depth (number of requests waiting to be sent to disk) */ + WqTime int64 /* accumulated wait queueing time */ + WqMinTime int64 /* min wait queueing time */ + WqMaxTime int64 /* max wait queueing time */ +} + +// Disk Adapter Types +const ( + DA_SCSI = 0 /* 0 ==> SCSI, SAS, other legacy adapter types */ + DA_VSCSI /* 1 ==> Virtual SCSI/SAS Adapter */ + DA_FCA /* 2 ==> Fiber Channel Adapter */ +) + +type DiskAdapter struct { + Name string /* name of the adapter (from ODM) */ + Description string /* adapter description (from ODM) */ + Number int32 /* number of disks connected to adapter */ + Size int64 /* total size of all disks (in MB) */ + Free int64 /* free portion of all disks (in MB) */ + XRate int64 /* __rxfers: total number of reads via adapter */ + Xfers int64 /* total number of transfers via adapter */ + Rblks int64 /* 512 bytes blocks written via adapter */ + Wblks int64 /* 512 bytes blocks read via adapter */ + Time int64 /* amount of time disks are active */ + Version int64 /* version number (1, 2, etc.,) */ + AdapterType int64 /* 0 ==> SCSI, SAS, other legacy adapter types, 1 ==> Virtual SCSI/SAS Adapter, 2 ==> Fiber Channel Adapter */ + DkBSize int64 /* Number of Bytes in a block for this disk*/ + DkRxfers int64 /* Number of transfers from disk */ + DkRserv int64 /* read or receive service time */ + DkWserv int64 /* write or send service time */ + MinRserv int64 /* Minimum read service time */ + MaxRserv int64 /* Maximum read service time */ + MinWserv int64 /* Minimum Write service time */ + MaxWserv int64 /* Maximum write service time */ + WqDepth int64 /* driver wait queue depth */ + WqSampled int64 /* accumulated sampled dk_wq_depth */ + WqTime int64 /* accumulated wait queueing time */ + WqMinTime int64 /* minimum wait queueing time */ + WqMaxTime int64 /* maximum wait queueing time */ + QFull int64 /* "Service" queue full occurrence count (number of times the adapter/devices connected to the adapter is not accepting any more request) */ + QSampled int64 /* accumulated sampled */ +} + +type Disk struct { + Name string /* name of the disk */ + Description string /* disk description (from ODM) */ + VGName string /* volume group name (from ODM) */ + Size int64 /* size of the disk (in MB) */ + Free int64 /* free portion of the disk (in MB) */ + BSize int64 /* disk block size (in bytes) */ + XRate int64 /* number of transfers from disk */ + Xfers int64 /* number of transfers to/from disk */ + Wblks int64 /* number of blocks written to disk */ + Rblks int64 /* number of blocks read from disk */ + QDepth int64 /* instantaneous "service" queue depth (number of requests sent to disk and not completed yet) */ + Time int64 /* amount of time disk is active */ + Adapter string /* disk adapter name */ + PathsCount int32 /* number of paths to this disk */ + QFull int64 /* "service" queue full occurrence count (number of times the disk is not accepting any more request) */ + Rserv int64 /* read or receive service time */ + RTimeOut int64 /* number of read request timeouts */ + Rfailed int64 /* number of failed read requests */ + MinRserv int64 /* min read or receive service time */ + MaxRserv int64 /* max read or receive service time */ + Wserv int64 /* write or send service time */ + WTimeOut int64 /* number of write request timeouts */ + Wfailed int64 /* number of failed write requests */ + MinWserv int64 /* min write or send service time */ + MaxWserv int64 /* max write or send service time */ + WqDepth int64 /* instantaneous wait queue depth (number of requests waiting to be sent to disk) */ + WqSampled int64 /* accumulated sampled dk_wq_depth */ + WqTime int64 /* accumulated wait queueing time */ + WqMinTime int64 /* min wait queueing time */ + WqMaxTime int64 /* max wait queueing time */ + QSampled int64 /* accumulated sampled dk_q_depth */ + Version int64 /* version number (1, 2, etc.,) */ + PseudoDisk bool /*Indicates whether pseudo or physical disk */ + VTDisk bool /* 1- Virtual Target Disk, 0 - Others */ +} + +type DiskPath struct { + Name string /* name of the path */ + XRate int64 /* __rxfers: number of reads via the path */ + Xfers int64 /* number of transfers via the path */ + Rblks int64 /* 512 bytes blocks written via the path */ + Wblks int64 /* 512 bytes blocks read via the path */ + Time int64 /* amount of time disks are active */ + Adapter string /* disk adapter name (from ODM) */ + QFull int64 /* "service" queue full occurrence count (number of times the disk is not accepting any more request) */ + Rserv int64 /* read or receive service time */ + RTimeOut int64 /* number of read request timeouts */ + Rfailed int64 /* number of failed read requests */ + MinRserv int64 /* min read or receive service time */ + MaxRserv int64 /* max read or receive service time */ + Wserv int64 /* write or send service time */ + WTimeOut int64 /* number of write request timeouts */ + Wfailed int64 /* number of failed write requests */ + MinWserv int64 /* min write or send service time */ + MaxWserv int64 /* max write or send service time */ + WqDepth int64 /* instantaneous wait queue depth (number of requests waiting to be sent to disk) */ + WqSampled int64 /* accumulated sampled dk_wq_depth */ + WqTime int64 /* accumulated wait queueing time */ + WqMinTime int64 /* min wait queueing time */ + WqMaxTime int64 /* max wait queueing time */ + QSampled int64 /* accumulated sampled dk_q_depth */ + Version int64 /* version number (1, 2, etc.,) */ +} + +const ( + FC_DOWN = 0 // FC Adapter state is DOWN + FC_UP = 1 // FC Adapter state is UP +) + +const ( + FCT_FCHBA = 0 // FC type - real Fiber Channel Adapter + FCT_VFC = 1 // FC type - virtual Fiber Channel +) + +type FCAdapter struct { + Version int64 /* version number (1, 2, etc.,) */ + Name string /* name of the adapter */ + State int32 /* FC Adapter state UP or DOWN */ + InputRequests int64 /* Number of Input Requests*/ + OutputRequests int64 /* Number of Output Requests */ + InputBytes int64 /* Number of Input Bytes */ + OutputBytes int64 /* Number of Output Bytes */ + EffMaxTransfer int64 /* Adapter's Effective Maximum Transfer Value */ + NoDMAResourceCnt int64 /* Count of DMA failures due to no DMA Resource available */ + NoCmdResourceCnt int64 /* Count of failures to allocate a command due to no command resource available */ + AttentionType int32 /* Link up or down Indicator */ + SecondsSinceLastReset int64 /* Displays the seconds since last reset of the statistics on the adapter */ + TxFrames int64 /* Number of frames transmitted */ + TxWords int64 /* Fiber Channel Kbytes transmitted */ + RxFrames int64 /* Number of Frames Received */ + RxWords int64 /* Fiber Channel Kbytes Received */ + LIPCount int64 /* Count of LIP (Loop Initialization Protocol) Events received in case we have FC-AL */ + NOSCount int64 /* Count of NOS (Not_Operational) Events. This indicates a link failure state. */ + ErrorFrames int64 /* Number of frames received with the CRC Error */ + DumpedFrames int64 /* Number of lost frames */ + LinkFailureCount int64 /* Count of Link failures */ + LossofSyncCount int64 /* Count of loss of sync */ + LossofSignal int64 /* Count of loss of Signal */ + PrimitiveSeqProtocolErrCount int64 /* number of times a primitive sequence was in error */ + InvalidTxWordCount int64 /* Count of Invalid Transmission words received */ + InvalidCRCCount int64 /* Count of CRC Errors in a Received Frame */ + PortFcId int64 /* SCSI Id of the adapter */ + PortSpeed int64 /* Speed of Adapter in GBIT */ + PortType string /* Type of connection. The Possible Values are Fabric, Private Loop, Point-to-Point, unknown */ + PortWWN int64 /* World Wide Port name */ + PortSupportedSpeed int64 /* Supported Port Speed in GBIT */ + AdapterType int /* 0 - Fiber Chanel, 1 - Virtual Fiber Chanel Adapter */ + VfcName string /* name of the Virtual Fiber Chanel(VFC) adapter */ + ClientPartName string /* name of the client partition */ +} diff --git a/vendor/github.com/power-devops/perfstat/types_fs.go b/vendor/github.com/power-devops/perfstat/types_fs.go new file mode 100644 index 0000000000..0be048a384 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_fs.go @@ -0,0 +1,195 @@ +package perfstat + +import ( + "strings" +) + +type FileSystem struct { + Device string /* name of the mounted device */ + MountPoint string /* where the device is mounted */ + FSType int /* File system type, see the constants below */ + Flags int /* Flags of the file system */ + TotalBlocks int64 /* number of 512 bytes blocks in the filesystem */ + FreeBlocks int64 /* number of free 512 bytes block in the filesystem */ + TotalInodes int64 /* total number of inodes in the filesystem */ + FreeInodes int64 /* number of free inodes in the filesystem */ +} + +func (f *FileSystem) TypeString() string { + switch f.FSType { + case FS_JFS2: + return "jfs2" + case FS_NAMEFS: + return "namefs" + case FS_NFS: + return "nfs" + case FS_JFS: + return "jfs" + case FS_CDROM: + return "cdrfs" + case FS_PROCFS: + return "procfs" + case FS_SFS: + return "sfs" + case FS_CACHEFS: + return "cachefs" + case FS_NFS3: + return "nfs3" + case FS_AUTOFS: + return "autofs" + case FS_POOLFS: + return "poolfs" + case FS_VXFS: + return "vxfs" + case FS_VXODM: + return "vxodm" + case FS_UDF: + return "udfs" + case FS_NFS4: + return "nfs4" + case FS_RFS4: + return "rfs4" + case FS_CIFS: + return "cifs" + case FS_PMEMFS: + return "pmemfs" + case FS_AHAFS: + return "ahafs" + case FS_STNFS: + return "stnfs" + case FS_ASMFS: + return "asmfs" + } + return "unknown" +} + +func (f *FileSystem) FlagsString() string { + var flags []string + + switch { + case f.Flags&VFS_READONLY != 0: + flags = append(flags, "ro") + case f.Flags&VFS_REMOVABLE != 0: + flags = append(flags, "removable") + case f.Flags&VFS_DEVMOUNT != 0: + flags = append(flags, "local") + case f.Flags&VFS_REMOTE != 0: + flags = append(flags, "remote") + case f.Flags&VFS_SYSV_MOUNT != 0: + flags = append(flags, "sysv") + case f.Flags&VFS_UNMOUNTING != 0: + flags = append(flags, "unmounting") + case f.Flags&VFS_NOSUID != 0: + flags = append(flags, "nosuid") + case f.Flags&VFS_NODEV != 0: + flags = append(flags, "nodev") + case f.Flags&VFS_NOINTEG != 0: + flags = append(flags, "nointeg") + case f.Flags&VFS_NOMANAGER != 0: + flags = append(flags, "nomanager") + case f.Flags&VFS_NOCASE != 0: + flags = append(flags, "nocase") + case f.Flags&VFS_UPCASE != 0: + flags = append(flags, "upcase") + case f.Flags&VFS_NBC != 0: + flags = append(flags, "nbc") + case f.Flags&VFS_MIND != 0: + flags = append(flags, "mind") + case f.Flags&VFS_RBR != 0: + flags = append(flags, "rbr") + case f.Flags&VFS_RBW != 0: + flags = append(flags, "rbw") + case f.Flags&VFS_DISCONNECTED != 0: + flags = append(flags, "disconnected") + case f.Flags&VFS_SHUTDOWN != 0: + flags = append(flags, "shutdown") + case f.Flags&VFS_VMOUNTOK != 0: + flags = append(flags, "vmountok") + case f.Flags&VFS_SUSER != 0: + flags = append(flags, "suser") + case f.Flags&VFS_SOFT_MOUNT != 0: + flags = append(flags, "soft") + case f.Flags&VFS_UNMOUNTED != 0: + flags = append(flags, "unmounted") + case f.Flags&VFS_DEADMOUNT != 0: + flags = append(flags, "deadmount") + case f.Flags&VFS_SNAPSHOT != 0: + flags = append(flags, "snapshot") + case f.Flags&VFS_VCM_ON != 0: + flags = append(flags, "vcm_on") + case f.Flags&VFS_VCM_MONITOR != 0: + flags = append(flags, "vcm_monitor") + case f.Flags&VFS_ATIMEOFF != 0: + flags = append(flags, "noatime") + case f.Flags&VFS_READMOSTLY != 0: + flags = append(flags, "readmostly") + case f.Flags&VFS_CIOR != 0: + flags = append(flags, "cior") + case f.Flags&VFS_CIO != 0: + flags = append(flags, "cio") + case f.Flags&VFS_DIO != 0: + flags = append(flags, "dio") + } + + return strings.Join(flags, ",") +} + +// Filesystem types +const ( + FS_JFS2 = 0 /* AIX physical fs "jfs2" */ + FS_NAMEFS = 1 /* AIX pseudo fs "namefs" */ + FS_NFS = 2 /* SUN Network File System "nfs" */ + FS_JFS = 3 /* AIX R3 physical fs "jfs" */ + FS_CDROM = 5 /* CDROM File System "cdrom" */ + FS_PROCFS = 6 /* PROCFS File System "proc" */ + FS_SFS = 16 /* AIX Special FS (STREAM mounts) */ + FS_CACHEFS = 17 /* Cachefs file system */ + FS_NFS3 = 18 /* NFSv3 file system */ + FS_AUTOFS = 19 /* Automount file system */ + FS_POOLFS = 20 /* Pool file system */ + FS_VXFS = 32 /* THRPGIO File System "vxfs" */ + FS_VXODM = 33 /* For Veritas File System */ + FS_UDF = 34 /* UDFS file system */ + FS_NFS4 = 35 /* NFSv4 file system */ + FS_RFS4 = 36 /* NFSv4 Pseudo file system */ + FS_CIFS = 37 /* AIX SMBFS (CIFS client) */ + FS_PMEMFS = 38 /* MCR Async Mobility pseudo file system */ + FS_AHAFS = 39 /* AHAFS File System "aha" */ + FS_STNFS = 40 /* Short-Term NFS */ + FS_ASMFS = 41 /* Oracle ASM FS */ +) + +// Filesystem flags +const ( + VFS_READONLY = 0x00000001 /* rdonly access to vfs */ + VFS_REMOVABLE = 0x00000002 /* removable (diskette) media */ + VFS_DEVMOUNT = 0x00000004 /* physical device mount */ + VFS_REMOTE = 0x00000008 /* file system is on network */ + VFS_SYSV_MOUNT = 0x00000010 /* System V style mount */ + VFS_UNMOUNTING = 0x00000020 /* originated by unmount() */ + VFS_NOSUID = 0x00000040 /* don't maintain suid-ness across this mount */ + VFS_NODEV = 0x00000080 /* don't allow device access across this mount */ + VFS_NOINTEG = 0x00000100 /* no integrity mount option */ + VFS_NOMANAGER = 0x00000200 /* mount managed fs w/o manager */ + VFS_NOCASE = 0x00000400 /* do not map dir names */ + VFS_UPCASE = 0x00000800 /* map dir names to uppercase */ + VFS_NBC = 0x00001000 /* NBC cached file in this vfs */ + VFS_MIND = 0x00002000 /* multi-segment .indirect */ + VFS_RBR = 0x00004000 /* Release-behind when reading */ + VFS_RBW = 0x00008000 /* Release-behind when writing */ + VFS_DISCONNECTED = 0x00010000 /* file mount not in use */ + VFS_SHUTDOWN = 0x00020000 /* forced unmount for shutdown */ + VFS_VMOUNTOK = 0x00040000 /* dir/file mnt permission flag */ + VFS_SUSER = 0x00080000 /* client-side suser perm. flag */ + VFS_SOFT_MOUNT = 0x00100000 /* file-over-file or directory over directory "soft" mount */ + VFS_UNMOUNTED = 0x00200000 /* unmount completed, stale vnodes are left in the vfs */ + VFS_DEADMOUNT = 0x00400000 /* softmount vfs should be disconnected at last vnode free */ + VFS_SNAPSHOT = 0x00800000 /* snapshot mount */ + VFS_VCM_ON = 0x01000000 /* VCM is currently active */ + VFS_VCM_MONITOR = 0x02000000 /* VCM monitoring is active */ + VFS_ATIMEOFF = 0x04000000 /* no atime updates during i/o */ + VFS_READMOSTLY = 0x10000000 /* ROFS allows open for write */ + VFS_CIOR = 0x20000000 /* O_CIOR mount */ + VFS_CIO = 0x40000000 /* O_CIO mount */ + VFS_DIO = 0x80000000 /* O_DIRECT mount */ +) diff --git a/vendor/github.com/power-devops/perfstat/types_lpar.go b/vendor/github.com/power-devops/perfstat/types_lpar.go new file mode 100644 index 0000000000..2d3c32fa8c --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_lpar.go @@ -0,0 +1,68 @@ +package perfstat + +type PartitionType struct { + SmtCapable bool /* OS supports SMT mode */ + SmtEnabled bool /* SMT mode is on */ + LparCapable bool /* OS supports logical partitioning */ + LparEnabled bool /* logical partitioning is on */ + SharedCapable bool /* OS supports shared processor LPAR */ + SharedEnabled bool /* partition runs in shared mode */ + DLparCapable bool /* OS supports dynamic LPAR */ + Capped bool /* partition is capped */ + Kernel64bit bool /* kernel is 64 bit */ + PoolUtilAuthority bool /* pool utilization available */ + DonateCapable bool /* capable of donating cycles */ + DonateEnabled bool /* enabled for donating cycles */ + AmsCapable bool /* 1 = AMS(Active Memory Sharing) capable, 0 = Not AMS capable */ + AmsEnabled bool /* 1 = AMS(Active Memory Sharing) enabled, 0 = Not AMS enabled */ + PowerSave bool /*1= Power saving mode is enabled*/ + AmeEnabled bool /* Active Memory Expansion is enabled */ + SharedExtended bool +} + +type PartitionValue struct { + Online int64 + Max int64 + Min int64 + Desired int64 +} + +type PartitionConfig struct { + Version int64 /* Version number */ + Name string /* Partition Name */ + Node string /* Node Name */ + Conf PartitionType /* Partition Properties */ + Number int32 /* Partition Number */ + GroupID int32 /* Group ID */ + ProcessorFamily string /* Processor Type */ + ProcessorModel string /* Processor Model */ + MachineID string /* Machine ID */ + ProcessorMhz float64 /* Processor Clock Speed in MHz */ + NumProcessors PartitionValue /* Number of Configured Physical Processors in frame*/ + OSName string /* Name of Operating System */ + OSVersion string /* Version of operating System */ + OSBuild string /* Build of Operating System */ + LCpus int32 /* Number of Logical CPUs */ + SmtThreads int32 /* Number of SMT Threads */ + Drives int32 /* Total Number of Drives */ + NetworkAdapters int32 /* Total Number of Network Adapters */ + CpuCap PartitionValue /* Min, Max and Online CPU Capacity */ + Weightage int32 /* Variable Processor Capacity Weightage */ + EntCapacity int32 /* number of processor units this partition is entitled to receive */ + VCpus PartitionValue /* Min, Max and Online Virtual CPUs */ + PoolID int32 /* Shared Pool ID of physical processors, to which this partition belongs*/ + ActiveCpusInPool int32 /* Count of physical CPUs in the shared processor pool, to which this partition belongs */ + PoolWeightage int32 /* Pool Weightage */ + SharedPCpu int32 /* Number of physical processors allocated for shared processor use */ + MaxPoolCap int32 /* Maximum processor capacity of partition's pool */ + EntPoolCap int32 /* Entitled processor capacity of partition's pool */ + Mem PartitionValue /* Min, Max and Online Memory */ + MemWeightage int32 /* Variable Memory Capacity Weightage */ + TotalIOMemoryEntitlement int64 /* I/O Memory Entitlement of the partition in bytes */ + MemPoolID int32 /* AMS pool id of the pool the LPAR belongs to */ + HyperPgSize int64 /* Hypervisor page size in KB*/ + ExpMem PartitionValue /* Min, Max and Online Expanded Memory */ + TargetMemExpFactor int64 /* Target Memory Expansion Factor scaled by 100 */ + TargetMemExpSize int64 /* Expanded Memory Size in MB */ + SubProcessorMode int32 /* Split core mode, its value can be 0,1,2 or 4. 0 for unsupported, 1 for capable but not enabled, 2 or 4 for enabled*/ +} diff --git a/vendor/github.com/power-devops/perfstat/types_lvm.go b/vendor/github.com/power-devops/perfstat/types_lvm.go new file mode 100644 index 0000000000..8f7176a613 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_lvm.go @@ -0,0 +1,31 @@ +package perfstat + +type LogicalVolume struct { + Name string /* logical volume name */ + VGName string /* volume group name */ + OpenClose int64 /* LVM_QLVOPEN, etc. (see lvm.h) */ + State int64 /* LVM_UNDEF, etc. (see lvm.h) */ + MirrorPolicy int64 /* LVM_PARALLEL, etc. (see lvm.h) */ + MirrorWriteConsistency int64 /* LVM_CONSIST, etc. (see lvm.h) */ + WriteVerify int64 /* LVM_VERIFY, etc. (see lvm.h) */ + PPsize int64 /* physical partition size in MB */ + LogicalPartitions int64 /* total number of logical paritions configured for this logical volume */ + Mirrors int32 /* number of physical mirrors for each logical partition */ + IOCnt int64 /* Number of read and write requests */ + KBReads int64 /* Number of Kilobytes read */ + KBWrites int64 /* Number of Kilobytes written */ + Version int64 /* version number (1, 2, etc.,) */ +} + +type VolumeGroup struct { + Name string /* volume group name */ + TotalDisks int64 /* number of physical volumes in the volume group */ + ActiveDisks int64 /* number of active physical volumes in the volume group */ + TotalLogicalVolumes int64 /* number of logical volumes in the volume group */ + OpenedLogicalVolumes int64 /* number of logical volumes opened in the volume group */ + IOCnt int64 /* Number of read and write requests */ + KBReads int64 /* Number of Kilobytes read */ + KBWrites int64 /* Number of Kilobytes written */ + Version int64 /* version number (1, 2, etc.,) */ + VariedState int /* Indicates volume group available or not */ +} diff --git a/vendor/github.com/power-devops/perfstat/types_memory.go b/vendor/github.com/power-devops/perfstat/types_memory.go new file mode 100644 index 0000000000..096d29ad2e --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_memory.go @@ -0,0 +1,101 @@ +package perfstat + +type MemoryTotal struct { + VirtualTotal int64 /* total virtual memory (in 4KB pages) */ + RealTotal int64 /* total real memory (in 4KB pages) */ + RealFree int64 /* free real memory (in 4KB pages) */ + RealPinned int64 /* real memory which is pinned (in 4KB pages) */ + RealInUse int64 /* real memory which is in use (in 4KB pages) */ + BadPages int64 /* number of bad pages */ + PageFaults int64 /* number of page faults */ + PageIn int64 /* number of pages paged in */ + PageOut int64 /* number of pages paged out */ + PgSpIn int64 /* number of page ins from paging space */ + PgSpOut int64 /* number of page outs from paging space */ + Scans int64 /* number of page scans by clock */ + Cycles int64 /* number of page replacement cycles */ + PgSteals int64 /* number of page steals */ + NumPerm int64 /* number of frames used for files (in 4KB pages) */ + PgSpTotal int64 /* total paging space (in 4KB pages) */ + PgSpFree int64 /* free paging space (in 4KB pages) */ + PgSpRsvd int64 /* reserved paging space (in 4KB pages) */ + RealSystem int64 /* real memory used by system segments (in 4KB pages). */ + RealUser int64 /* real memory used by non-system segments (in 4KB pages). */ + RealProcess int64 /* real memory used by process segments (in 4KB pages). */ + VirtualActive int64 /* Active virtual pages. Virtual pages are considered active if they have been accessed */ + IOME int64 /* I/O memory entitlement of the partition in bytes*/ + IOMU int64 /* I/O memory entitlement of the partition in use in bytes*/ + IOHWM int64 /* High water mark of I/O memory entitlement used in bytes*/ + PMem int64 /* Amount of physical mmeory currently backing partition's logical memory in bytes*/ + CompressedTotal int64 /* Total numbers of pages in compressed pool (in 4KB pages) */ + CompressedWSegPg int64 /* Number of compressed working storage pages */ + CPgIn int64 /* number of page ins to compressed pool */ + CPgOut int64 /* number of page outs from compressed pool */ + TrueSize int64 /* True Memory Size in 4KB pages */ + ExpandedMemory int64 /* Expanded Memory Size in 4KB pages */ + CompressedWSegSize int64 /* Total size of the compressed working storage pages in the pool */ + TargetCPoolSize int64 /* Target Compressed Pool Size in bytes */ + MaxCPoolSize int64 /* Max Size of Compressed Pool in bytes */ + MinUCPoolSize int64 /* Min Size of Uncompressed Pool in bytes */ + CPoolSize int64 /* Compressed Pool size in bytes */ + UCPoolSize int64 /* Uncompressed Pool size in bytes */ + CPoolInUse int64 /* Compressed Pool Used in bytes */ + UCPoolInUse int64 /* Uncompressed Pool Used in bytes */ + Version int64 /* version number (1, 2, etc.,) */ + RealAvailable int64 /* number of pages (in 4KB pages) of memory available without paging out working segments */ + BytesCoalesced int64 /* The number of bytes of the calling partition.s logical real memory coalesced because they contained duplicated data */ + BytesCoalescedMemPool int64 /* number of bytes of logical real memory coalesced because they contained duplicated data in the calling partition.s memory */ +} + +type MemoryPage struct { + PSize int64 /* page size in bytes */ + RealTotal int64 /* number of real memory frames of this page size */ + RealFree int64 /* number of pages on free list */ + RealPinned int64 /* number of pages pinned */ + RealInUse int64 /* number of pages in use */ + PgExct int64 /* number of page faults */ + PgIns int64 /* number of pages paged in */ + PgOuts int64 /* number of pages paged out */ + PgSpIns int64 /* number of page ins from paging space */ + PgSpOuts int64 /* number of page outs from paging space */ + Scans int64 /* number of page scans by clock */ + Cycles int64 /* number of page replacement cycles */ + PgSteals int64 /* number of page steals */ + NumPerm int64 /* number of frames used for files */ + NumPgSp int64 /* number of pages with allocated paging space */ + RealSystem int64 /* number of pages used by system segments. */ + RealUser int64 /* number of pages used by non-system segments. */ + RealProcess int64 /* number of pages used by process segments. */ + VirtActive int64 /* Active virtual pages. */ + ComprsdTotal int64 /* Number of pages of this size compressed */ + ComprsdWsegPgs int64 /* Number of compressed working storage pages */ + CPgIns int64 /* number of page ins of this page size to compressed pool */ + CPgOuts int64 /* number of page outs of this page size from compressed pool */ + CPoolInUse int64 /* Compressed Size of this page size in Compressed Pool */ + UCPoolSize int64 /* Uncompressed Pool size in bytes of this page size */ + ComprsdWsegSize int64 /* Total size of the compressed working storage pages in the pool */ + Version int64 /* version number (1, 2, etc.,) */ + RealAvail int64 /* number of pages (in 4KB pages) of memory available without paging out working segments */ +} + +// paging space types +const ( + LV_PAGING = 1 + NFS_PAGING = 2 + UNKNOWN_PAGING = 3 +) + +type PagingSpace struct { + Name string /* Paging space name */ + Type uint8 /* type of paging device (LV_PAGING or NFS_PAGING) */ + VGName string /* volume group name */ + Hostname string /* host name of paging server */ + Filename string /* swap file name on server */ + LPSize int64 /* size in number of logical partitions */ + MBSize int64 /* size in megabytes */ + MBUsed int64 /* portion used in megabytes */ + IOPending int64 /* number of pending I/O */ + Active uint8 /* indicates if active (1 if so, 0 if not) */ + Automatic uint8 /* indicates if automatic (1 if so, 0 if not) */ + Version int64 /* version number (1, 2, etc.,) */ +} diff --git a/vendor/github.com/power-devops/perfstat/types_network.go b/vendor/github.com/power-devops/perfstat/types_network.go new file mode 100644 index 0000000000..e69d0041d3 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_network.go @@ -0,0 +1,163 @@ +package perfstat + +// Network Interface types +const ( + IFT_OTHER = 0x1 + IFT_1822 = 0x2 /* old-style arpanet imp */ + IFT_HDH1822 = 0x3 /* HDH arpanet imp */ + IFT_X25DDN = 0x4 /* x25 to imp */ + IFT_X25 = 0x5 /* PDN X25 interface (RFC877) */ + IFT_ETHER = 0x6 /* Ethernet CSMACD */ + IFT_ISO88023 = 0x7 /* CMSA CD */ + IFT_ISO88024 = 0x8 /* Token Bus */ + IFT_ISO88025 = 0x9 /* Token Ring */ + IFT_ISO88026 = 0xa /* MAN */ + IFT_STARLAN = 0xb + IFT_P10 = 0xc /* Proteon 10MBit ring */ + IFT_P80 = 0xd /* Proteon 10MBit ring */ + IFT_HY = 0xe /* Hyperchannel */ + IFT_FDDI = 0xf + IFT_LAPB = 0x10 + IFT_SDLC = 0x11 + IFT_T1 = 0x12 + IFT_CEPT = 0x13 /* E1 - european T1 */ + IFT_ISDNBASIC = 0x14 + IFT_ISDNPRIMARY = 0x15 + IFT_PTPSERIAL = 0x16 /* Proprietary PTP serial */ + IFT_PPP = 0x17 /* RFC 1331 */ + IFT_LOOP = 0x18 /* loopback */ + IFT_EON = 0x19 /* ISO over IP */ + IFT_XETHER = 0x1a /* obsolete 3MB experimental ethernet */ + IFT_NSIP = 0x1b /* XNS over IP */ + IFT_SLIP = 0x1c /* IP over generic TTY */ + IFT_ULTRA = 0x1d /* Ultra Technologies */ + IFT_DS3 = 0x1e /* Generic T3 */ + IFT_SIP = 0x1f /* SMDS */ + IFT_FRELAY = 0x20 /* Frame Relay DTE only */ + IFT_RS232 = 0x21 + IFT_PARA = 0x22 /* parallel-port */ + IFT_ARCNET = 0x23 + IFT_ARCNETPLUS = 0x24 + IFT_ATM = 0x25 /* ATM cells */ + IFT_MIOX25 = 0x26 + IFT_SONET = 0x27 /* SONET or SDH */ + IFT_X25PLE = 0x28 + IFT_ISO88022LLC = 0x29 + IFT_LOCALTALK = 0x2a + IFT_SMDSDXI = 0x2b + IFT_FRELAYDCE = 0x2c /* Frame Relay DCE */ + IFT_V35 = 0x2d + IFT_HSSI = 0x2e + IFT_HIPPI = 0x2f + IFT_MODEM = 0x30 /* Generic Modem */ + IFT_AAL5 = 0x31 /* AAL5 over ATM */ + IFT_SONETPATH = 0x32 + IFT_SONETVT = 0x33 + IFT_SMDSICIP = 0x34 /* SMDS InterCarrier Interface */ + IFT_PROPVIRTUAL = 0x35 /* Proprietary Virtual/internal */ + IFT_PROPMUX = 0x36 /* Proprietary Multiplexing */ + IFT_VIPA = 0x37 /* Virtual Interface */ + IFT_SN = 0x38 /* Federation Switch */ + IFT_SP = 0x39 /* SP switch */ + IFT_FCS = 0x3a /* IP over Fiber Channel */ + IFT_TUNNEL = 0x3b + IFT_GIFTUNNEL = 0x3c /* IPv4 over IPv6 tunnel */ + IFT_HF = 0x3d /* Support for PERCS HFI*/ + IFT_CLUSTER = 0x3e /* cluster pseudo network interface */ + IFT_FB = 0xc7 /* IP over Infiniband. Number by IANA */ +) + +type NetIfaceTotal struct { + Number int32 /* number of network interfaces */ + IPackets int64 /* number of packets received on interface */ + IBytes int64 /* number of bytes received on interface */ + IErrors int64 /* number of input errors on interface */ + OPackets int64 /* number of packets sent on interface */ + OBytes int64 /* number of bytes sent on interface */ + OErrors int64 /* number of output errors on interface */ + Collisions int64 /* number of collisions on csma interface */ + XmitDrops int64 /* number of packets not transmitted */ + Version int64 /* version number (1, 2, etc.,) */ +} + +type NetIface struct { + Name string /* name of the interface */ + Description string /* interface description (from ODM, similar to lscfg output) */ + Type uint8 /* ethernet, tokenring, etc. interpretation can be done using /usr/include/net/if_types.h */ + MTU int64 /* network frame size */ + IPackets int64 /* number of packets received on interface */ + IBytes int64 /* number of bytes received on interface */ + IErrors int64 /* number of input errors on interface */ + OPackets int64 /* number of packets sent on interface */ + OBytes int64 /* number of bytes sent on interface */ + OErrors int64 /* number of output errors on interface */ + Collisions int64 /* number of collisions on csma interface */ + Bitrate int64 /* adapter rating in bit per second */ + XmitDrops int64 /* number of packets not transmitted */ + Version int64 /* version number (1, 2, etc.,) */ + IfIqDrops int64 /* Dropped on input, this interface */ + IfArpDrops int64 /* Dropped because no arp response */ +} + +type NetBuffer struct { + Name string /* size in ascii, always power of 2 (ex: "32", "64", "128") */ + InUse int64 /* number of buffer currently allocated */ + Calls int64 /* number of buffer allocations since last reset */ + Delayed int64 /* number of delayed allocations */ + Free int64 /* number of free calls */ + Failed int64 /* number of failed allocations */ + HighWatermark int64 /* high threshold for number of buffer allocated */ + Freed int64 /* number of buffers freed */ + Version int64 /* version number (1, 2, etc.,) */ +} + +// Network adapter types +const ( + NET_PHY = 0 /* physical device */ + NET_SEA = 1 /* shared ethernet adapter */ + NET_VIR = 2 /* virtual device */ + NET_HEA = 3 /* host ethernet adapter */ + NET_EC = 4 /* etherchannel */ + NET_VLAN = 5 /* vlan pseudo device */ +) + +type NetAdapter struct { + Version int64 /* version number (1,2, etc) */ + Name string /* name of the adapter */ + TxPackets int64 /* Transmit Packets on interface */ + TxBytes int64 /* Transmit Bytes on interface */ + TxInterrupts int64 /* Transfer Interrupts */ + TxErrors int64 /* Transmit Errors */ + TxPacketsDropped int64 /* Packets Dropped at the time of Data Transmission */ + TxQueueSize int64 /* Maximum Packets on Software Transmit Queue */ + TxQueueLen int64 /* Transmission Queue Length */ + TxQueueOverflow int64 /* Transmission Queue Overflow */ + TxBroadcastPackets int64 /* Number of Broadcast Packets Transmitted */ + TxMulticastPackets int64 /* Number of Multicast packets Transmitted */ + TxCarrierSense int64 /* Lost Carrier Sense signal count */ + TxDMAUnderrun int64 /* Count of DMA Under-runs for Transmission */ + TxLostCTSErrors int64 /* The number of unsuccessful transmissions due to the loss of the Clear-to-Send signal error */ + TxMaxCollisionErrors int64 /* Maximum Collision Errors at Transmission */ + TxLateCollisionErrors int64 /* Late Collision Errors at Transmission */ + TxDeferred int64 /* The number of packets deferred for Transmission. */ + TxTimeoutErrors int64 /* Time Out Errors for Transmission */ + TxSingleCollisionCount int64 /* Count of Single Collision error at Transmission */ + TxMultipleCollisionCount int64 /* Count of Multiple Collision error at Transmission */ + RxPackets int64 /* Receive Packets on interface */ + RxBytes int64 /* Receive Bytes on interface */ + RxInterrupts int64 /* Receive Interrupts */ + RxErrors int64 /* Input errors on interface */ + RxPacketsDropped int64 /* The number of packets accepted by the device driver for transmission which were not (for any reason) given to the device. */ + RxBadPackets int64 /* Count of Bad Packets Received. */ + RxMulticastPackets int64 /* Number of MultiCast Packets Received */ + RxBroadcastPackets int64 /* Number of Broadcast Packets Received */ + RxCRCErrors int64 /* Count of Packets Received with CRC errors */ + RxDMAOverrun int64 /* Count of DMA over-runs for Data Receival. */ + RxAlignmentErrors int64 /* Packets Received with Alignment Error */ + RxNoResourceErrors int64 /* Packets Received with No Resource Errors */ + RxCollisionErrors int64 /* Packets Received with Collision errors */ + RxPacketTooShortErrors int64 /* Count of Short Packets Received. */ + RxPacketTooLongErrors int64 /* Count of Too Long Packets Received. */ + RxPacketDiscardedByAdapter int64 /* Count of Received Packets discarded by Adapter. */ + AdapterType int32 /* 0 - Physical, 1 - SEA, 2 - Virtual, 3 -HEA */ +} diff --git a/vendor/github.com/power-devops/perfstat/types_process.go b/vendor/github.com/power-devops/perfstat/types_process.go new file mode 100644 index 0000000000..325c70b077 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/types_process.go @@ -0,0 +1,43 @@ +package perfstat + +type Process struct { + Version int64 /* version number (1, 2, etc.,) */ + PID int64 /* Process ID */ + ProcessName string /* Name of The Process */ + Priority int32 /* Process Priority */ + NumThreads int64 /* Thread Count */ + UID int64 /* Owner Info */ + ClassID int64 /* WLM Class Name */ + Size int64 /* Virtual Size of the Process in KB(Exclusive Usage, Leaving all Shared Library Text & Shared File Pages, Shared Memory, Memory Mapped) */ + RealMemData int64 /* Real Memory used for Data in KB */ + RealMemText int64 /* Real Memory used for Text in KB */ + VirtMemData int64 /* Virtual Memory used to Data in KB */ + VirtMemText int64 /* Virtual Memory used for Text in KB */ + SharedLibDataSize int64 /* Data Size from Shared Library in KB */ + HeapSize int64 /* Heap Size in KB */ + RealInUse int64 /* The Real memory in use(in KB) by the process including all kind of segments (excluding system segments). This includes Text, Data, Shared Library Text, Shared Library Data, File Pages, Shared Memory & Memory Mapped */ + VirtInUse int64 /* The Virtual memory in use(in KB) by the process including all kind of segments (excluding system segments). This includes Text, Data, Shared Library Text, Shared Library Data, File Pages, Shared Memory & Memory Mapped */ + Pinned int64 /* Pinned Memory(in KB) for this process inclusive of all segments */ + PgSpInUse int64 /* Paging Space used(in KB) inclusive of all segments */ + FilePages int64 /* File Pages used(in KB) including shared pages */ + RealInUseMap int64 /* Real memory used(in KB) for Shared Memory and Memory Mapped regions */ + VirtInUseMap int64 /* Virtual Memory used(in KB) for Shared Memory and Memory Mapped regions */ + PinnedInUseMap int64 /* Pinned memory(in KB) for Shared Memory and Memory Mapped regions */ + UCpuTime float64 /* User Mode CPU time will be in percentage or milliseconds based on, whether it is filled by perfstat_process_util or perfstat_process respectively. */ + SCpuTime float64 /* System Mode CPU time will be in percentage or milliseconds based on, whether it is filled by perfstat_process_util or perfstat_process respectively. */ + LastTimeBase int64 /* Timebase Counter */ + InBytes int64 /* Bytes Read from Disk */ + OutBytes int64 /* Bytes Written to Disk */ + InOps int64 /* In Operations from Disk */ + OutOps int64 /* Out Operations from Disk */ +} + +type Thread struct { + TID int64 /* thread identifier */ + PID int64 /* process identifier */ + CpuID int64 /* processor on which I'm bound */ + UCpuTime float64 /* User Mode CPU time will be in percentage or milliseconds based on, whether it is filled by perfstat_thread_util or perfstat_thread respectively. */ + SCpuTime float64 /* System Mode CPU time will be in percentage or milliseconds based on, whether it is filled by perfstat_thread_util or perfstat_thread respectively. */ + LastTimeBase int64 /* Timebase Counter */ + Version int64 +} diff --git a/vendor/github.com/power-devops/perfstat/uptime.go b/vendor/github.com/power-devops/perfstat/uptime.go new file mode 100644 index 0000000000..2bd3e568d2 --- /dev/null +++ b/vendor/github.com/power-devops/perfstat/uptime.go @@ -0,0 +1,35 @@ +// +build aix + +package perfstat + +/* +#include "c_helpers.h" +*/ +import "C" + +import ( + "fmt" + "time" +) + +func timeSince(ts uint64) uint64 { + return uint64(time.Now().Unix()) - ts +} + +// BootTime() returns the time of the last boot in UNIX seconds +func BootTime() (uint64, error) { + sec := C.boottime() + if sec == -1 { + return 0, fmt.Errorf("Can't determine boot time") + } + return uint64(sec), nil +} + +// UptimeSeconds() calculates uptime in seconds +func UptimeSeconds() (uint64, error) { + boot, err := BootTime() + if err != nil { + return 0, err + } + return timeSince(boot), nil +} diff --git a/vendor/github.com/shirou/gopsutil/v3/LICENSE b/vendor/github.com/shirou/gopsutil/v3/LICENSE new file mode 100644 index 0000000000..6f06adcbff --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/LICENSE @@ -0,0 +1,61 @@ +gopsutil is distributed under BSD license reproduced below. + +Copyright (c) 2014, WAKAYAMA Shirou +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the gopsutil authors nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +------- +internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. + + + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/shirou/gopsutil/v3/common/env.go b/vendor/github.com/shirou/gopsutil/v3/common/env.go new file mode 100644 index 0000000000..4b5f4980c2 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/common/env.go @@ -0,0 +1,23 @@ +package common + +type EnvKeyType string + +// EnvKey is a context key that can be used to set programmatically the environment +// gopsutil relies on to perform calls against the OS. +// Example of use: +// +// ctx := context.WithValue(context.Background(), common.EnvKey, EnvMap{common.HostProcEnvKey: "/myproc"}) +// avg, err := load.AvgWithContext(ctx) +var EnvKey = EnvKeyType("env") + +const ( + HostProcEnvKey EnvKeyType = "HOST_PROC" + HostSysEnvKey EnvKeyType = "HOST_SYS" + HostEtcEnvKey EnvKeyType = "HOST_ETC" + HostVarEnvKey EnvKeyType = "HOST_VAR" + HostRunEnvKey EnvKeyType = "HOST_RUN" + HostDevEnvKey EnvKeyType = "HOST_DEV" + HostRootEnvKey EnvKeyType = "HOST_ROOT" +) + +type EnvMap map[EnvKeyType]string diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk.go new file mode 100644 index 0000000000..0d4b25345e --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk.go @@ -0,0 +1,98 @@ +package disk + +import ( + "context" + "encoding/json" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +var invoke common.Invoker = common.Invoke{} + +type Warnings = common.Warnings + +type UsageStat struct { + Path string `json:"path"` + Fstype string `json:"fstype"` + Total uint64 `json:"total"` + Free uint64 `json:"free"` + Used uint64 `json:"used"` + UsedPercent float64 `json:"usedPercent"` + InodesTotal uint64 `json:"inodesTotal"` + InodesUsed uint64 `json:"inodesUsed"` + InodesFree uint64 `json:"inodesFree"` + InodesUsedPercent float64 `json:"inodesUsedPercent"` +} + +type PartitionStat struct { + Device string `json:"device"` + Mountpoint string `json:"mountpoint"` + Fstype string `json:"fstype"` + Opts []string `json:"opts"` +} + +type IOCountersStat struct { + ReadCount uint64 `json:"readCount"` + MergedReadCount uint64 `json:"mergedReadCount"` + WriteCount uint64 `json:"writeCount"` + MergedWriteCount uint64 `json:"mergedWriteCount"` + ReadBytes uint64 `json:"readBytes"` + WriteBytes uint64 `json:"writeBytes"` + ReadTime uint64 `json:"readTime"` + WriteTime uint64 `json:"writeTime"` + IopsInProgress uint64 `json:"iopsInProgress"` + IoTime uint64 `json:"ioTime"` + WeightedIO uint64 `json:"weightedIO"` + Name string `json:"name"` + SerialNumber string `json:"serialNumber"` + Label string `json:"label"` +} + +func (d UsageStat) String() string { + s, _ := json.Marshal(d) + return string(s) +} + +func (d PartitionStat) String() string { + s, _ := json.Marshal(d) + return string(s) +} + +func (d IOCountersStat) String() string { + s, _ := json.Marshal(d) + return string(s) +} + +// Usage returns a file system usage. path is a filesystem path such +// as "/", not device file path like "/dev/vda1". If you want to use +// a return value of disk.Partitions, use "Mountpoint" not "Device". +func Usage(path string) (*UsageStat, error) { + return UsageWithContext(context.Background(), path) +} + +// Partitions returns disk partitions. If all is false, returns +// physical devices only (e.g. hard disks, cd-rom drives, USB keys) +// and ignore all others (e.g. memory partitions such as /dev/shm) +// +// 'all' argument is ignored for BSD, see: https://github.com/giampaolo/psutil/issues/906 +func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +// SerialNumber returns Serial Number of given device or empty string +// on error. Name of device is expected, eg. /dev/sda +func SerialNumber(name string) (string, error) { + return SerialNumberWithContext(context.Background(), name) +} + +// Label returns label of given device or empty string on error. +// Name of device is expected, eg. /dev/sda +// Supports label based on devicemapper name +// See https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-block-dm +func Label(name string) (string, error) { + return LabelWithContext(context.Background(), name) +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix.go new file mode 100644 index 0000000000..bc71712eac --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix.go @@ -0,0 +1,22 @@ +//go:build aix +// +build aix + +package disk + +import ( + "context" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + return nil, common.ErrNotImplementedError +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_cgo.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_cgo.go new file mode 100644 index 0000000000..aa534df30c --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_cgo.go @@ -0,0 +1,76 @@ +//go:build aix && cgo +// +build aix,cgo + +package disk + +import ( + "context" + "fmt" + + "github.com/power-devops/perfstat" +) + +var FSType map[int]string + +func init() { + FSType = map[int]string{ + 0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc", + 16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs", + 33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs", + 39: "ahafs", 40: "sterm-nfs", 41: "asmfs", + } +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + f, err := perfstat.FileSystemStat() + if err != nil { + return nil, err + } + ret := make([]PartitionStat, len(f)) + + for _, fs := range f { + fstyp, exists := FSType[fs.FSType] + if !exists { + fstyp = "unknown" + } + info := PartitionStat{ + Device: fs.Device, + Mountpoint: fs.MountPoint, + Fstype: fstyp, + } + ret = append(ret, info) + } + + return ret, err +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + f, err := perfstat.FileSystemStat() + if err != nil { + return nil, err + } + + blocksize := uint64(512) + for _, fs := range f { + if path == fs.MountPoint { + fstyp, exists := FSType[fs.FSType] + if !exists { + fstyp = "unknown" + } + info := UsageStat{ + Path: path, + Fstype: fstyp, + Total: uint64(fs.TotalBlocks) * blocksize, + Free: uint64(fs.FreeBlocks) * blocksize, + Used: uint64(fs.TotalBlocks-fs.FreeBlocks) * blocksize, + InodesTotal: uint64(fs.TotalInodes), + InodesFree: uint64(fs.FreeInodes), + InodesUsed: uint64(fs.TotalInodes - fs.FreeInodes), + } + info.UsedPercent = (float64(info.Used) / float64(info.Total)) * 100.0 + info.InodesUsedPercent = (float64(info.InodesUsed) / float64(info.InodesTotal)) * 100.0 + return &info, nil + } + } + return nil, fmt.Errorf("mountpoint %s not found", path) +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_nocgo.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_nocgo.go new file mode 100644 index 0000000000..17e2b9c844 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_aix_nocgo.go @@ -0,0 +1,81 @@ +//go:build aix && !cgo +// +build aix,!cgo + +package disk + +import ( + "context" + "regexp" + "strings" + + "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/unix" +) + +var startBlank = regexp.MustCompile(`^\s+`) + +var ignoreFSType = map[string]bool{"procfs": true} +var FSType = map[int]string{ + 0: "jfs2", 1: "namefs", 2: "nfs", 3: "jfs", 5: "cdrom", 6: "proc", + 16: "special-fs", 17: "cache-fs", 18: "nfs3", 19: "automount-fs", 20: "pool-fs", 32: "vxfs", + 33: "veritas-fs", 34: "udfs", 35: "nfs4", 36: "nfs4-pseudo", 37: "smbfs", 38: "mcr-pseudofs", + 39: "ahafs", 40: "sterm-nfs", 41: "asmfs", +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + var ret []PartitionStat + + out, err := invoke.CommandWithContext(ctx, "mount") + if err != nil { + return nil, err + } + + // parse head lines for column names + colidx := make(map[string]int) + lines := strings.Split(string(out), "\n") + if len(lines) < 3 { + return nil, common.ErrNotImplementedError + } + + idx := 0 + start := 0 + finished := false + for pos, ch := range lines[1] { + if ch == ' ' && !finished { + name := strings.TrimSpace(lines[0][start:pos]) + colidx[name] = idx + finished = true + } else if ch == '-' && finished { + idx++ + start = pos + finished = false + } + } + name := strings.TrimSpace(lines[0][start:len(lines[1])]) + colidx[name] = idx + + for idx := 2; idx < len(lines); idx++ { + line := lines[idx] + if startBlank.MatchString(line) { + line = "localhost" + line + } + p := strings.Fields(lines[idx]) + if len(p) < 5 || ignoreFSType[p[colidx["vfs"]]] { + continue + } + d := PartitionStat{ + Device: p[colidx["mounted"]], + Mountpoint: p[colidx["mounted over"]], + Fstype: p[colidx["vfs"]], + Opts: strings.Split(p[colidx["options"]], ","), + } + + ret = append(ret, d) + } + + return ret, nil +} + +func getFsType(stat unix.Statfs_t) string { + return FSType[int(stat.Vfstype)] +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin.go new file mode 100644 index 0000000000..9362d9e5de --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin.go @@ -0,0 +1,94 @@ +//go:build darwin +// +build darwin + +package disk + +import ( + "context" + + "golang.org/x/sys/unix" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +// PartitionsWithContext returns disk partition. +// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906 +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + var ret []PartitionStat + + count, err := unix.Getfsstat(nil, unix.MNT_WAIT) + if err != nil { + return ret, err + } + fs := make([]unix.Statfs_t, count) + count, err = unix.Getfsstat(fs, unix.MNT_WAIT) + if err != nil { + return ret, err + } + // On 10.14, and possibly other OS versions, the actual count may + // be less than from the first call. Truncate to the returned count + // to prevent accessing uninitialized entries. + // https://github.com/shirou/gopsutil/issues/1390 + fs = fs[:count] + for _, stat := range fs { + opts := []string{"rw"} + if stat.Flags&unix.MNT_RDONLY != 0 { + opts = []string{"ro"} + } + if stat.Flags&unix.MNT_SYNCHRONOUS != 0 { + opts = append(opts, "sync") + } + if stat.Flags&unix.MNT_NOEXEC != 0 { + opts = append(opts, "noexec") + } + if stat.Flags&unix.MNT_NOSUID != 0 { + opts = append(opts, "nosuid") + } + if stat.Flags&unix.MNT_UNION != 0 { + opts = append(opts, "union") + } + if stat.Flags&unix.MNT_ASYNC != 0 { + opts = append(opts, "async") + } + if stat.Flags&unix.MNT_DONTBROWSE != 0 { + opts = append(opts, "nobrowse") + } + if stat.Flags&unix.MNT_AUTOMOUNTED != 0 { + opts = append(opts, "automounted") + } + if stat.Flags&unix.MNT_JOURNALED != 0 { + opts = append(opts, "journaled") + } + if stat.Flags&unix.MNT_MULTILABEL != 0 { + opts = append(opts, "multilabel") + } + if stat.Flags&unix.MNT_NOATIME != 0 { + opts = append(opts, "noatime") + } + if stat.Flags&unix.MNT_NODEV != 0 { + opts = append(opts, "nodev") + } + d := PartitionStat{ + Device: common.ByteToString(stat.Mntfromname[:]), + Mountpoint: common.ByteToString(stat.Mntonname[:]), + Fstype: common.ByteToString(stat.Fstypename[:]), + Opts: opts, + } + + ret = append(ret, d) + } + + return ret, nil +} + +func getFsType(stat unix.Statfs_t) string { + return common.ByteToString(stat.Fstypename[:]) +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_cgo.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_cgo.go new file mode 100644 index 0000000000..27c24c9224 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_cgo.go @@ -0,0 +1,45 @@ +//go:build darwin && cgo && !ios +// +build darwin,cgo,!ios + +package disk + +/* +#cgo LDFLAGS: -framework CoreFoundation -framework IOKit +#include +#include +#include "iostat_darwin.h" +*/ +import "C" + +import ( + "context" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + var buf [C.NDRIVE]C.DriveStats + n, err := C.gopsutil_v3_readdrivestat(&buf[0], C.int(len(buf))) + if err != nil { + return nil, err + } + ret := make(map[string]IOCountersStat, 0) + for i := 0; i < int(n); i++ { + d := IOCountersStat{ + ReadBytes: uint64(buf[i].read), + WriteBytes: uint64(buf[i].written), + ReadCount: uint64(buf[i].nread), + WriteCount: uint64(buf[i].nwrite), + ReadTime: uint64(buf[i].readtime / 1000 / 1000), // note: read/write time are in ns, but we want ms. + WriteTime: uint64(buf[i].writetime / 1000 / 1000), + IoTime: uint64((buf[i].readtime + buf[i].writetime) / 1000 / 1000), + Name: C.GoString(&buf[i].name[0]), + } + if len(names) > 0 && !common.StringsHas(names, d.Name) { + continue + } + + ret[d.Name] = d + } + return ret, nil +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_nocgo.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_nocgo.go new file mode 100644 index 0000000000..1f099b7caa --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_darwin_nocgo.go @@ -0,0 +1,14 @@ +//go:build (darwin && !cgo) || ios +// +build darwin,!cgo ios + +package disk + +import ( + "context" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + return nil, common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_fallback.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_fallback.go new file mode 100644 index 0000000000..36525f694b --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_fallback.go @@ -0,0 +1,30 @@ +//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !windows && !solaris && !aix +// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!windows,!solaris,!aix + +package disk + +import ( + "context" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + return nil, common.ErrNotImplementedError +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + return []PartitionStat{}, common.ErrNotImplementedError +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + return nil, common.ErrNotImplementedError +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd.go new file mode 100644 index 0000000000..9b53106c2a --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd.go @@ -0,0 +1,192 @@ +//go:build freebsd +// +build freebsd + +package disk + +import ( + "bufio" + "bytes" + "context" + "encoding/binary" + "fmt" + "strconv" + "strings" + + "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/unix" +) + +// PartitionsWithContext returns disk partition. +// 'all' argument is ignored, see: https://github.com/giampaolo/psutil/issues/906 +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + var ret []PartitionStat + + // get length + count, err := unix.Getfsstat(nil, unix.MNT_WAIT) + if err != nil { + return ret, err + } + + fs := make([]unix.Statfs_t, count) + if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil { + return ret, err + } + + for _, stat := range fs { + opts := []string{"rw"} + if stat.Flags&unix.MNT_RDONLY != 0 { + opts = []string{"ro"} + } + if stat.Flags&unix.MNT_SYNCHRONOUS != 0 { + opts = append(opts, "sync") + } + if stat.Flags&unix.MNT_NOEXEC != 0 { + opts = append(opts, "noexec") + } + if stat.Flags&unix.MNT_NOSUID != 0 { + opts = append(opts, "nosuid") + } + if stat.Flags&unix.MNT_UNION != 0 { + opts = append(opts, "union") + } + if stat.Flags&unix.MNT_ASYNC != 0 { + opts = append(opts, "async") + } + if stat.Flags&unix.MNT_SUIDDIR != 0 { + opts = append(opts, "suiddir") + } + if stat.Flags&unix.MNT_SOFTDEP != 0 { + opts = append(opts, "softdep") + } + if stat.Flags&unix.MNT_NOSYMFOLLOW != 0 { + opts = append(opts, "nosymfollow") + } + if stat.Flags&unix.MNT_GJOURNAL != 0 { + opts = append(opts, "gjournal") + } + if stat.Flags&unix.MNT_MULTILABEL != 0 { + opts = append(opts, "multilabel") + } + if stat.Flags&unix.MNT_ACLS != 0 { + opts = append(opts, "acls") + } + if stat.Flags&unix.MNT_NOATIME != 0 { + opts = append(opts, "noatime") + } + if stat.Flags&unix.MNT_NOCLUSTERR != 0 { + opts = append(opts, "noclusterr") + } + if stat.Flags&unix.MNT_NOCLUSTERW != 0 { + opts = append(opts, "noclusterw") + } + if stat.Flags&unix.MNT_NFS4ACLS != 0 { + opts = append(opts, "nfsv4acls") + } + + d := PartitionStat{ + Device: common.ByteToString(stat.Mntfromname[:]), + Mountpoint: common.ByteToString(stat.Mntonname[:]), + Fstype: common.ByteToString(stat.Fstypename[:]), + Opts: opts, + } + + ret = append(ret, d) + } + + return ret, nil +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + // statinfo->devinfo->devstat + // /usr/include/devinfo.h + ret := make(map[string]IOCountersStat) + + r, err := unix.Sysctl("kern.devstat.all") + if err != nil { + return nil, err + } + buf := []byte(r) + length := len(buf) + + count := int(uint64(length) / uint64(sizeOfdevstat)) + + buf = buf[8:] // devstat.all has version in the head. + // parse buf to devstat + for i := 0; i < count; i++ { + b := buf[i*sizeOfdevstat : i*sizeOfdevstat+sizeOfdevstat] + d, err := parsedevstat(b) + if err != nil { + continue + } + un := strconv.Itoa(int(d.Unit_number)) + name := common.IntToString(d.Device_name[:]) + un + + if len(names) > 0 && !common.StringsHas(names, name) { + continue + } + + ds := IOCountersStat{ + ReadCount: d.Operations[devstat_READ], + WriteCount: d.Operations[devstat_WRITE], + ReadBytes: d.Bytes[devstat_READ], + WriteBytes: d.Bytes[devstat_WRITE], + ReadTime: uint64(d.Duration[devstat_READ].Compute() * 1000), + WriteTime: uint64(d.Duration[devstat_WRITE].Compute() * 1000), + IoTime: uint64(d.Busy_time.Compute() * 1000), + Name: name, + } + ds.SerialNumber, _ = SerialNumberWithContext(ctx, name) + ret[name] = ds + } + + return ret, nil +} + +func (b bintime) Compute() float64 { + BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20 + return float64(b.Sec) + float64(b.Frac)*BINTIME_SCALE +} + +// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE) + +func parsedevstat(buf []byte) (devstat, error) { + var ds devstat + br := bytes.NewReader(buf) + // err := binary.Read(br, binary.LittleEndian, &ds) + err := common.Read(br, binary.LittleEndian, &ds) + if err != nil { + return ds, err + } + + return ds, nil +} + +func getFsType(stat unix.Statfs_t) string { + return common.ByteToString(stat.Fstypename[:]) +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + geomOut, err := invoke.CommandWithContext(ctx, "geom", "disk", "list", name) + if err != nil { + return "", fmt.Errorf("exec geom: %w", err) + } + s := bufio.NewScanner(bytes.NewReader(geomOut)) + serial := "" + for s.Scan() { + flds := strings.Fields(s.Text()) + if len(flds) == 2 && flds[0] == "ident:" { + if flds[1] != "(null)" { + serial = flds[1] + } + break + } + } + if err = s.Err(); err != nil { + return "", err + } + return serial, nil +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_386.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_386.go new file mode 100644 index 0000000000..7fa1783dcb --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_386.go @@ -0,0 +1,63 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package disk + +const ( + sizeofPtr = 0x4 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x4 + sizeofLongLong = 0x8 + sizeofLongDouble = 0x8 + + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfdevstat = 0xf0 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int32 + _C_long_long int64 + _C_long_double int64 +) + +type devstat struct { + Sequence0 uint32 + Allocated int32 + Start_count uint32 + End_count uint32 + Busy_from bintime + Dev_links _Ctype_struct___0 + Device_number uint32 + Device_name [16]int8 + Unit_number int32 + Bytes [4]uint64 + Operations [4]uint64 + Duration [4]bintime + Busy_time bintime + Creation_time bintime + Block_size uint32 + Tag_types [3]uint64 + Flags uint32 + Device_type uint32 + Priority uint32 + Id *byte + Sequence1 uint32 +} + +type bintime struct { + Sec int32 + Frac uint64 +} + +type _Ctype_struct___0 struct { + Empty uint32 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_amd64.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_amd64.go new file mode 100644 index 0000000000..d86a308be8 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_amd64.go @@ -0,0 +1,66 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package disk + +const ( + sizeofPtr = 0x8 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x8 + sizeofLongLong = 0x8 + sizeofLongDouble = 0x8 + + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfdevstat = 0x120 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 + _C_long_double int64 +) + +type devstat struct { + Sequence0 uint32 + Allocated int32 + Start_count uint32 + End_count uint32 + Busy_from bintime + Dev_links _Ctype_struct___0 + Device_number uint32 + Device_name [16]int8 + Unit_number int32 + Bytes [4]uint64 + Operations [4]uint64 + Duration [4]bintime + Busy_time bintime + Creation_time bintime + Block_size uint32 + Pad_cgo_0 [4]byte + Tag_types [3]uint64 + Flags uint32 + Device_type uint32 + Priority uint32 + Pad_cgo_1 [4]byte + ID *byte + Sequence1 uint32 + Pad_cgo_2 [4]byte +} + +type bintime struct { + Sec int64 + Frac uint64 +} + +type _Ctype_struct___0 struct { + Empty uint64 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm.go new file mode 100644 index 0000000000..7fa1783dcb --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm.go @@ -0,0 +1,63 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package disk + +const ( + sizeofPtr = 0x4 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x4 + sizeofLongLong = 0x8 + sizeofLongDouble = 0x8 + + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfdevstat = 0xf0 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int32 + _C_long_long int64 + _C_long_double int64 +) + +type devstat struct { + Sequence0 uint32 + Allocated int32 + Start_count uint32 + End_count uint32 + Busy_from bintime + Dev_links _Ctype_struct___0 + Device_number uint32 + Device_name [16]int8 + Unit_number int32 + Bytes [4]uint64 + Operations [4]uint64 + Duration [4]bintime + Busy_time bintime + Creation_time bintime + Block_size uint32 + Tag_types [3]uint64 + Flags uint32 + Device_type uint32 + Priority uint32 + Id *byte + Sequence1 uint32 +} + +type bintime struct { + Sec int32 + Frac uint64 +} + +type _Ctype_struct___0 struct { + Empty uint32 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm64.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm64.go new file mode 100644 index 0000000000..f6b3f80df4 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_freebsd_arm64.go @@ -0,0 +1,66 @@ +//go:build freebsd && arm64 +// +build freebsd,arm64 + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs disk/types_freebsd.go + +package disk + +const ( + sizeofPtr = 0x8 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x8 + sizeofLongLong = 0x8 + sizeofLongDouble = 0x8 + + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfdevstat = 0x120 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 + _C_long_double int64 +) + +type devstat struct { + Sequence0 uint32 + Allocated int32 + Start_count uint32 + End_count uint32 + Busy_from bintime + Dev_links _Ctype_struct___0 + Device_number uint32 + Device_name [16]int8 + Unit_number int32 + Bytes [4]uint64 + Operations [4]uint64 + Duration [4]bintime + Busy_time bintime + Creation_time bintime + Block_size uint32 + Tag_types [3]uint64 + Flags uint32 + Device_type uint32 + Priority uint32 + Id *byte + Sequence1 uint32 + Pad_cgo_0 [4]byte +} +type bintime struct { + Sec int64 + Frac uint64 +} + +type _Ctype_struct___0 struct { + Empty uint64 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_linux.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_linux.go new file mode 100644 index 0000000000..ada9f9e76c --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_linux.go @@ -0,0 +1,561 @@ +//go:build linux +// +build linux + +package disk + +import ( + "bufio" + "context" + "errors" + "fmt" + "os" + "path" + "path/filepath" + "strconv" + "strings" + + "golang.org/x/sys/unix" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +const ( + sectorSize = 512 +) + +const ( + // man statfs + ADFS_SUPER_MAGIC = 0xadf5 + AFFS_SUPER_MAGIC = 0xADFF + BDEVFS_MAGIC = 0x62646576 + BEFS_SUPER_MAGIC = 0x42465331 + BFS_MAGIC = 0x1BADFACE + BINFMTFS_MAGIC = 0x42494e4d + BTRFS_SUPER_MAGIC = 0x9123683E + CGROUP_SUPER_MAGIC = 0x27e0eb + CIFS_MAGIC_NUMBER = 0xFF534D42 + CODA_SUPER_MAGIC = 0x73757245 + COH_SUPER_MAGIC = 0x012FF7B7 + CRAMFS_MAGIC = 0x28cd3d45 + DEBUGFS_MAGIC = 0x64626720 + DEVFS_SUPER_MAGIC = 0x1373 + DEVPTS_SUPER_MAGIC = 0x1cd1 + EFIVARFS_MAGIC = 0xde5e81e4 + EFS_SUPER_MAGIC = 0x00414A53 + EXT_SUPER_MAGIC = 0x137D + EXT2_OLD_SUPER_MAGIC = 0xEF51 + EXT2_SUPER_MAGIC = 0xEF53 + EXT3_SUPER_MAGIC = 0xEF53 + EXT4_SUPER_MAGIC = 0xEF53 + FUSE_SUPER_MAGIC = 0x65735546 + FUTEXFS_SUPER_MAGIC = 0xBAD1DEA + HFS_SUPER_MAGIC = 0x4244 + HFSPLUS_SUPER_MAGIC = 0x482b + HOSTFS_SUPER_MAGIC = 0x00c0ffee + HPFS_SUPER_MAGIC = 0xF995E849 + HUGETLBFS_MAGIC = 0x958458f6 + ISOFS_SUPER_MAGIC = 0x9660 + JFFS2_SUPER_MAGIC = 0x72b6 + JFS_SUPER_MAGIC = 0x3153464a + MINIX_SUPER_MAGIC = 0x137F /* orig. minix */ + MINIX_SUPER_MAGIC2 = 0x138F /* 30 char minix */ + MINIX2_SUPER_MAGIC = 0x2468 /* minix V2 */ + MINIX2_SUPER_MAGIC2 = 0x2478 /* minix V2, 30 char names */ + MINIX3_SUPER_MAGIC = 0x4d5a /* minix V3 fs, 60 char names */ + MQUEUE_MAGIC = 0x19800202 + MSDOS_SUPER_MAGIC = 0x4d44 + NCP_SUPER_MAGIC = 0x564c + NFS_SUPER_MAGIC = 0x6969 + NILFS_SUPER_MAGIC = 0x3434 + NTFS_SB_MAGIC = 0x5346544e + OCFS2_SUPER_MAGIC = 0x7461636f + OPENPROM_SUPER_MAGIC = 0x9fa1 + PIPEFS_MAGIC = 0x50495045 + PROC_SUPER_MAGIC = 0x9fa0 + PSTOREFS_MAGIC = 0x6165676C + QNX4_SUPER_MAGIC = 0x002f + QNX6_SUPER_MAGIC = 0x68191122 + RAMFS_MAGIC = 0x858458f6 + REISERFS_SUPER_MAGIC = 0x52654973 + ROMFS_MAGIC = 0x7275 + SELINUX_MAGIC = 0xf97cff8c + SMACK_MAGIC = 0x43415d53 + SMB_SUPER_MAGIC = 0x517B + SOCKFS_MAGIC = 0x534F434B + SQUASHFS_MAGIC = 0x73717368 + SYSFS_MAGIC = 0x62656572 + SYSV2_SUPER_MAGIC = 0x012FF7B6 + SYSV4_SUPER_MAGIC = 0x012FF7B5 + TMPFS_MAGIC = 0x01021994 + UDF_SUPER_MAGIC = 0x15013346 + UFS_MAGIC = 0x00011954 + USBDEVICE_SUPER_MAGIC = 0x9fa2 + V9FS_MAGIC = 0x01021997 + VXFS_SUPER_MAGIC = 0xa501FCF5 + XENFS_SUPER_MAGIC = 0xabba1974 + XENIX_SUPER_MAGIC = 0x012FF7B4 + XFS_SUPER_MAGIC = 0x58465342 + _XIAFS_SUPER_MAGIC = 0x012FD16D + + AFS_SUPER_MAGIC = 0x5346414F + AUFS_SUPER_MAGIC = 0x61756673 + ANON_INODE_FS_SUPER_MAGIC = 0x09041934 + BPF_FS_MAGIC = 0xCAFE4A11 + CEPH_SUPER_MAGIC = 0x00C36400 + CGROUP2_SUPER_MAGIC = 0x63677270 + CONFIGFS_MAGIC = 0x62656570 + ECRYPTFS_SUPER_MAGIC = 0xF15F + F2FS_SUPER_MAGIC = 0xF2F52010 + FAT_SUPER_MAGIC = 0x4006 + FHGFS_SUPER_MAGIC = 0x19830326 + FUSEBLK_SUPER_MAGIC = 0x65735546 + FUSECTL_SUPER_MAGIC = 0x65735543 + GFS_SUPER_MAGIC = 0x1161970 + GPFS_SUPER_MAGIC = 0x47504653 + MTD_INODE_FS_SUPER_MAGIC = 0x11307854 + INOTIFYFS_SUPER_MAGIC = 0x2BAD1DEA + ISOFS_R_WIN_SUPER_MAGIC = 0x4004 + ISOFS_WIN_SUPER_MAGIC = 0x4000 + JFFS_SUPER_MAGIC = 0x07C0 + KAFS_SUPER_MAGIC = 0x6B414653 + LUSTRE_SUPER_MAGIC = 0x0BD00BD0 + NFSD_SUPER_MAGIC = 0x6E667364 + NSFS_MAGIC = 0x6E736673 + PANFS_SUPER_MAGIC = 0xAAD7AAEA + RPC_PIPEFS_SUPER_MAGIC = 0x67596969 + SECURITYFS_SUPER_MAGIC = 0x73636673 + TRACEFS_MAGIC = 0x74726163 + UFS_BYTESWAPPED_SUPER_MAGIC = 0x54190100 + VMHGFS_SUPER_MAGIC = 0xBACBACBC + VZFS_SUPER_MAGIC = 0x565A4653 + ZFS_SUPER_MAGIC = 0x2FC12FC1 +) + +// coreutils/src/stat.c +var fsTypeMap = map[int64]string{ + ADFS_SUPER_MAGIC: "adfs", /* 0xADF5 local */ + AFFS_SUPER_MAGIC: "affs", /* 0xADFF local */ + AFS_SUPER_MAGIC: "afs", /* 0x5346414F remote */ + ANON_INODE_FS_SUPER_MAGIC: "anon-inode FS", /* 0x09041934 local */ + AUFS_SUPER_MAGIC: "aufs", /* 0x61756673 remote */ + // AUTOFS_SUPER_MAGIC: "autofs", /* 0x0187 local */ + BEFS_SUPER_MAGIC: "befs", /* 0x42465331 local */ + BDEVFS_MAGIC: "bdevfs", /* 0x62646576 local */ + BFS_MAGIC: "bfs", /* 0x1BADFACE local */ + BINFMTFS_MAGIC: "binfmt_misc", /* 0x42494E4D local */ + BPF_FS_MAGIC: "bpf", /* 0xCAFE4A11 local */ + BTRFS_SUPER_MAGIC: "btrfs", /* 0x9123683E local */ + CEPH_SUPER_MAGIC: "ceph", /* 0x00C36400 remote */ + CGROUP_SUPER_MAGIC: "cgroupfs", /* 0x0027E0EB local */ + CGROUP2_SUPER_MAGIC: "cgroup2fs", /* 0x63677270 local */ + CIFS_MAGIC_NUMBER: "cifs", /* 0xFF534D42 remote */ + CODA_SUPER_MAGIC: "coda", /* 0x73757245 remote */ + COH_SUPER_MAGIC: "coh", /* 0x012FF7B7 local */ + CONFIGFS_MAGIC: "configfs", /* 0x62656570 local */ + CRAMFS_MAGIC: "cramfs", /* 0x28CD3D45 local */ + DEBUGFS_MAGIC: "debugfs", /* 0x64626720 local */ + DEVFS_SUPER_MAGIC: "devfs", /* 0x1373 local */ + DEVPTS_SUPER_MAGIC: "devpts", /* 0x1CD1 local */ + ECRYPTFS_SUPER_MAGIC: "ecryptfs", /* 0xF15F local */ + EFIVARFS_MAGIC: "efivarfs", /* 0xDE5E81E4 local */ + EFS_SUPER_MAGIC: "efs", /* 0x00414A53 local */ + EXT_SUPER_MAGIC: "ext", /* 0x137D local */ + EXT2_SUPER_MAGIC: "ext2/ext3", /* 0xEF53 local */ + EXT2_OLD_SUPER_MAGIC: "ext2", /* 0xEF51 local */ + F2FS_SUPER_MAGIC: "f2fs", /* 0xF2F52010 local */ + FAT_SUPER_MAGIC: "fat", /* 0x4006 local */ + FHGFS_SUPER_MAGIC: "fhgfs", /* 0x19830326 remote */ + FUSEBLK_SUPER_MAGIC: "fuseblk", /* 0x65735546 remote */ + FUSECTL_SUPER_MAGIC: "fusectl", /* 0x65735543 remote */ + FUTEXFS_SUPER_MAGIC: "futexfs", /* 0x0BAD1DEA local */ + GFS_SUPER_MAGIC: "gfs/gfs2", /* 0x1161970 remote */ + GPFS_SUPER_MAGIC: "gpfs", /* 0x47504653 remote */ + HFS_SUPER_MAGIC: "hfs", /* 0x4244 local */ + HFSPLUS_SUPER_MAGIC: "hfsplus", /* 0x482b local */ + HPFS_SUPER_MAGIC: "hpfs", /* 0xF995E849 local */ + HUGETLBFS_MAGIC: "hugetlbfs", /* 0x958458F6 local */ + MTD_INODE_FS_SUPER_MAGIC: "inodefs", /* 0x11307854 local */ + INOTIFYFS_SUPER_MAGIC: "inotifyfs", /* 0x2BAD1DEA local */ + ISOFS_SUPER_MAGIC: "isofs", /* 0x9660 local */ + ISOFS_R_WIN_SUPER_MAGIC: "isofs", /* 0x4004 local */ + ISOFS_WIN_SUPER_MAGIC: "isofs", /* 0x4000 local */ + JFFS_SUPER_MAGIC: "jffs", /* 0x07C0 local */ + JFFS2_SUPER_MAGIC: "jffs2", /* 0x72B6 local */ + JFS_SUPER_MAGIC: "jfs", /* 0x3153464A local */ + KAFS_SUPER_MAGIC: "k-afs", /* 0x6B414653 remote */ + LUSTRE_SUPER_MAGIC: "lustre", /* 0x0BD00BD0 remote */ + MINIX_SUPER_MAGIC: "minix", /* 0x137F local */ + MINIX_SUPER_MAGIC2: "minix (30 char.)", /* 0x138F local */ + MINIX2_SUPER_MAGIC: "minix v2", /* 0x2468 local */ + MINIX2_SUPER_MAGIC2: "minix v2 (30 char.)", /* 0x2478 local */ + MINIX3_SUPER_MAGIC: "minix3", /* 0x4D5A local */ + MQUEUE_MAGIC: "mqueue", /* 0x19800202 local */ + MSDOS_SUPER_MAGIC: "msdos", /* 0x4D44 local */ + NCP_SUPER_MAGIC: "novell", /* 0x564C remote */ + NFS_SUPER_MAGIC: "nfs", /* 0x6969 remote */ + NFSD_SUPER_MAGIC: "nfsd", /* 0x6E667364 remote */ + NILFS_SUPER_MAGIC: "nilfs", /* 0x3434 local */ + NSFS_MAGIC: "nsfs", /* 0x6E736673 local */ + NTFS_SB_MAGIC: "ntfs", /* 0x5346544E local */ + OPENPROM_SUPER_MAGIC: "openprom", /* 0x9FA1 local */ + OCFS2_SUPER_MAGIC: "ocfs2", /* 0x7461636f remote */ + PANFS_SUPER_MAGIC: "panfs", /* 0xAAD7AAEA remote */ + PIPEFS_MAGIC: "pipefs", /* 0x50495045 remote */ + PROC_SUPER_MAGIC: "proc", /* 0x9FA0 local */ + PSTOREFS_MAGIC: "pstorefs", /* 0x6165676C local */ + QNX4_SUPER_MAGIC: "qnx4", /* 0x002F local */ + QNX6_SUPER_MAGIC: "qnx6", /* 0x68191122 local */ + RAMFS_MAGIC: "ramfs", /* 0x858458F6 local */ + REISERFS_SUPER_MAGIC: "reiserfs", /* 0x52654973 local */ + ROMFS_MAGIC: "romfs", /* 0x7275 local */ + RPC_PIPEFS_SUPER_MAGIC: "rpc_pipefs", /* 0x67596969 local */ + SECURITYFS_SUPER_MAGIC: "securityfs", /* 0x73636673 local */ + SELINUX_MAGIC: "selinux", /* 0xF97CFF8C local */ + SMB_SUPER_MAGIC: "smb", /* 0x517B remote */ + SOCKFS_MAGIC: "sockfs", /* 0x534F434B local */ + SQUASHFS_MAGIC: "squashfs", /* 0x73717368 local */ + SYSFS_MAGIC: "sysfs", /* 0x62656572 local */ + SYSV2_SUPER_MAGIC: "sysv2", /* 0x012FF7B6 local */ + SYSV4_SUPER_MAGIC: "sysv4", /* 0x012FF7B5 local */ + TMPFS_MAGIC: "tmpfs", /* 0x01021994 local */ + TRACEFS_MAGIC: "tracefs", /* 0x74726163 local */ + UDF_SUPER_MAGIC: "udf", /* 0x15013346 local */ + UFS_MAGIC: "ufs", /* 0x00011954 local */ + UFS_BYTESWAPPED_SUPER_MAGIC: "ufs", /* 0x54190100 local */ + USBDEVICE_SUPER_MAGIC: "usbdevfs", /* 0x9FA2 local */ + V9FS_MAGIC: "v9fs", /* 0x01021997 local */ + VMHGFS_SUPER_MAGIC: "vmhgfs", /* 0xBACBACBC remote */ + VXFS_SUPER_MAGIC: "vxfs", /* 0xA501FCF5 local */ + VZFS_SUPER_MAGIC: "vzfs", /* 0x565A4653 local */ + XENFS_SUPER_MAGIC: "xenfs", /* 0xABBA1974 local */ + XENIX_SUPER_MAGIC: "xenix", /* 0x012FF7B4 local */ + XFS_SUPER_MAGIC: "xfs", /* 0x58465342 local */ + _XIAFS_SUPER_MAGIC: "xia", /* 0x012FD16D local */ + ZFS_SUPER_MAGIC: "zfs", /* 0x2FC12FC1 local */ +} + +// readMountFile reads mountinfo or mounts file under the specified root path +// (eg, /proc/1, /proc/self, etc) +func readMountFile(root string) (lines []string, useMounts bool, filename string, err error) { + filename = path.Join(root, "mountinfo") + lines, err = common.ReadLines(filename) + if err != nil { + var pathErr *os.PathError + if !errors.As(err, &pathErr) { + return + } + // if kernel does not support 1/mountinfo, fallback to 1/mounts (<2.6.26) + useMounts = true + filename = path.Join(root, "mounts") + lines, err = common.ReadLines(filename) + if err != nil { + return + } + return + } + return +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + // by default, try "/proc/1/..." first + root := common.HostProcWithContext(ctx, path.Join("1")) + + // force preference for dirname of HOST_PROC_MOUNTINFO, if set #1271 + hpmPath := common.HostProcMountInfoWithContext(ctx) + if hpmPath != "" { + root = filepath.Dir(hpmPath) + } + + lines, useMounts, filename, err := readMountFile(root) + if err != nil { + if hpmPath != "" { // don't fallback with HOST_PROC_MOUNTINFO + return nil, err + } + // fallback to "/proc/self/..." #1159 + lines, useMounts, filename, err = readMountFile(common.HostProcWithContext(ctx, path.Join("self"))) + if err != nil { + return nil, err + } + } + + fs, err := getFileSystems(ctx) + if err != nil && !all { + return nil, err + } + + ret := make([]PartitionStat, 0, len(lines)) + + for _, line := range lines { + var d PartitionStat + if useMounts { + fields := strings.Fields(line) + + d = PartitionStat{ + Device: fields[0], + Mountpoint: unescapeFstab(fields[1]), + Fstype: fields[2], + Opts: strings.Fields(fields[3]), + } + + if !all { + if d.Device == "none" || !common.StringsHas(fs, d.Fstype) { + continue + } + } + } else { + // a line of 1/mountinfo has the following structure: + // 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue + // (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) + + // split the mountinfo line by the separator hyphen + parts := strings.Split(line, " - ") + if len(parts) != 2 { + return nil, fmt.Errorf("found invalid mountinfo line in file %s: %s ", filename, line) + } + + fields := strings.Fields(parts[0]) + blockDeviceID := fields[2] + mountPoint := fields[4] + mountOpts := strings.Split(fields[5], ",") + + if rootDir := fields[3]; rootDir != "" && rootDir != "/" { + mountOpts = append(mountOpts, "bind") + } + + fields = strings.Fields(parts[1]) + fstype := fields[0] + device := fields[1] + + d = PartitionStat{ + Device: device, + Mountpoint: unescapeFstab(mountPoint), + Fstype: fstype, + Opts: mountOpts, + } + + if !all { + if d.Device == "none" || !common.StringsHas(fs, d.Fstype) { + continue + } + } + + if strings.HasPrefix(d.Device, "/dev/mapper/") { + devpath, err := filepath.EvalSymlinks(common.HostDevWithContext(ctx, strings.Replace(d.Device, "/dev", "", 1))) + if err == nil { + d.Device = devpath + } + } + + // /dev/root is not the real device name + // so we get the real device name from its major/minor number + if d.Device == "/dev/root" { + devpath, err := os.Readlink(common.HostSysWithContext(ctx, "/dev/block/"+blockDeviceID)) + if err == nil { + d.Device = strings.Replace(d.Device, "root", filepath.Base(devpath), 1) + } + } + } + ret = append(ret, d) + } + + return ret, nil +} + +// getFileSystems returns supported filesystems from /proc/filesystems +func getFileSystems(ctx context.Context) ([]string, error) { + filename := common.HostProcWithContext(ctx, "filesystems") + lines, err := common.ReadLines(filename) + if err != nil { + return nil, err + } + var ret []string + for _, line := range lines { + if !strings.HasPrefix(line, "nodev") { + ret = append(ret, strings.TrimSpace(line)) + continue + } + t := strings.Split(line, "\t") + if len(t) != 2 || t[1] != "zfs" { + continue + } + ret = append(ret, strings.TrimSpace(t[1])) + } + + return ret, nil +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + filename := common.HostProcWithContext(ctx, "diskstats") + lines, err := common.ReadLines(filename) + if err != nil { + return nil, err + } + ret := make(map[string]IOCountersStat) + empty := IOCountersStat{} + + // use only basename such as "/dev/sda1" to "sda1" + for i, name := range names { + names[i] = filepath.Base(name) + } + + for _, line := range lines { + fields := strings.Fields(line) + if len(fields) < 14 { + // malformed line in /proc/diskstats, avoid panic by ignoring. + continue + } + name := fields[2] + + if len(names) > 0 && !common.StringsHas(names, name) { + continue + } + + reads, err := strconv.ParseUint((fields[3]), 10, 64) + if err != nil { + return ret, err + } + mergedReads, err := strconv.ParseUint((fields[4]), 10, 64) + if err != nil { + return ret, err + } + rbytes, err := strconv.ParseUint((fields[5]), 10, 64) + if err != nil { + return ret, err + } + rtime, err := strconv.ParseUint((fields[6]), 10, 64) + if err != nil { + return ret, err + } + writes, err := strconv.ParseUint((fields[7]), 10, 64) + if err != nil { + return ret, err + } + mergedWrites, err := strconv.ParseUint((fields[8]), 10, 64) + if err != nil { + return ret, err + } + wbytes, err := strconv.ParseUint((fields[9]), 10, 64) + if err != nil { + return ret, err + } + wtime, err := strconv.ParseUint((fields[10]), 10, 64) + if err != nil { + return ret, err + } + iopsInProgress, err := strconv.ParseUint((fields[11]), 10, 64) + if err != nil { + return ret, err + } + iotime, err := strconv.ParseUint((fields[12]), 10, 64) + if err != nil { + return ret, err + } + weightedIO, err := strconv.ParseUint((fields[13]), 10, 64) + if err != nil { + return ret, err + } + d := IOCountersStat{ + ReadBytes: rbytes * sectorSize, + WriteBytes: wbytes * sectorSize, + ReadCount: reads, + WriteCount: writes, + MergedReadCount: mergedReads, + MergedWriteCount: mergedWrites, + ReadTime: rtime, + WriteTime: wtime, + IopsInProgress: iopsInProgress, + IoTime: iotime, + WeightedIO: weightedIO, + } + if d == empty { + continue + } + d.Name = name + + // Names passed in can be full paths (/dev/sda) or just device names (sda). + // Since `name` here is already a basename, re-add the /dev path. + // This is not ideal, but we may break the API by changing how SerialNumberWithContext + // works. + d.SerialNumber, _ = SerialNumberWithContext(ctx, common.HostDevWithContext(ctx, name)) + d.Label, _ = LabelWithContext(ctx, name) + + ret[name] = d + } + return ret, nil +} + +func udevData(ctx context.Context, major uint32, minor uint32, name string) (string, error) { + udevDataPath := common.HostRunWithContext(ctx, fmt.Sprintf("udev/data/b%d:%d", major, minor)) + if f, err := os.Open(udevDataPath); err == nil { + defer f.Close() + scanner := bufio.NewScanner(f) + for scanner.Scan() { + values := strings.SplitN(scanner.Text(), "=", 3) + if len(values) == 2 && values[0] == name { + return values[1], nil + } + } + return "", scanner.Err() + } else if !os.IsNotExist(err) { + return "", err + } + return "", nil +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + var stat unix.Stat_t + if err := unix.Stat(name, &stat); err != nil { + return "", err + } + major := unix.Major(uint64(stat.Rdev)) + minor := unix.Minor(uint64(stat.Rdev)) + + sserial, _ := udevData(ctx, major, minor, "E:ID_SERIAL") + if sserial != "" { + return sserial, nil + } + + // Try to get the serial from sysfs, look at the disk device (minor 0) directly + // because if it is a partition it is not going to contain any device information + devicePath := common.HostSysWithContext(ctx, fmt.Sprintf("dev/block/%d:0/device", major)) + model, _ := os.ReadFile(filepath.Join(devicePath, "model")) + serial, _ := os.ReadFile(filepath.Join(devicePath, "serial")) + if len(model) > 0 && len(serial) > 0 { + return fmt.Sprintf("%s_%s", string(model), string(serial)), nil + } + return "", nil +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + // Try label based on devicemapper name + dmname_filename := common.HostSysWithContext(ctx, fmt.Sprintf("block/%s/dm/name", name)) + // Could errors.Join errs with Go >= 1.20 + if common.PathExists(dmname_filename) { + dmname, err := os.ReadFile(dmname_filename) + if err == nil { + return strings.TrimSpace(string(dmname)), nil + } + } + // Try udev data + var stat unix.Stat_t + if err := unix.Stat(common.HostDevWithContext(ctx, name), &stat); err != nil { + return "", err + } + major := unix.Major(uint64(stat.Rdev)) + minor := unix.Minor(uint64(stat.Rdev)) + + label, err := udevData(ctx, major, minor, "E:ID_FS_LABEL") + if err != nil { + return "", err + } + return label, nil +} + +func getFsType(stat unix.Statfs_t) string { + t := int64(stat.Type) + ret, ok := fsTypeMap[t] + if !ok { + return "" + } + return ret +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd.go new file mode 100644 index 0000000000..5976efadb3 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd.go @@ -0,0 +1,152 @@ +//go:build netbsd +// +build netbsd + +package disk + +import ( + "context" + "unsafe" + + "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/unix" +) + +const ( + // see sys/fstypes.h and `man 5 statvfs` + MNT_RDONLY = 0x00000001 /* read only filesystem */ + MNT_SYNCHRONOUS = 0x00000002 /* file system written synchronously */ + MNT_NOEXEC = 0x00000004 /* can't exec from filesystem */ + MNT_NOSUID = 0x00000008 /* don't honor setuid bits on fs */ + MNT_NODEV = 0x00000010 /* don't interpret special files */ + MNT_ASYNC = 0x00000040 /* file system written asynchronously */ + MNT_NOATIME = 0x04000000 /* Never update access times in fs */ + MNT_SOFTDEP = 0x80000000 /* Use soft dependencies */ +) + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + var ret []PartitionStat + + flag := uint64(1) // ST_WAIT/MNT_WAIT, see sys/fstypes.h + + // get required buffer size + emptyBufSize := 0 + r, _, err := unix.Syscall( + 483, // SYS___getvfsstat90 syscall + uintptr(unsafe.Pointer(nil)), + uintptr(unsafe.Pointer(&emptyBufSize)), + uintptr(unsafe.Pointer(&flag)), + ) + if err != 0 { + return ret, err + } + mountedFsCount := uint64(r) + + // calculate the buffer size + bufSize := sizeOfStatvfs * mountedFsCount + buf := make([]Statvfs, mountedFsCount) + + // request agian to get desired mount data + _, _, err = unix.Syscall( + 483, // SYS___getvfsstat90 syscall + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&bufSize)), + uintptr(unsafe.Pointer(&flag)), + ) + if err != 0 { + return ret, err + } + + for _, stat := range buf { + opts := []string{"rw"} + if stat.Flag&MNT_RDONLY != 0 { + opts = []string{"rw"} + } + if stat.Flag&MNT_SYNCHRONOUS != 0 { + opts = append(opts, "sync") + } + if stat.Flag&MNT_NOEXEC != 0 { + opts = append(opts, "noexec") + } + if stat.Flag&MNT_NOSUID != 0 { + opts = append(opts, "nosuid") + } + if stat.Flag&MNT_NODEV != 0 { + opts = append(opts, "nodev") + } + if stat.Flag&MNT_ASYNC != 0 { + opts = append(opts, "async") + } + if stat.Flag&MNT_SOFTDEP != 0 { + opts = append(opts, "softdep") + } + if stat.Flag&MNT_NOATIME != 0 { + opts = append(opts, "noatime") + } + + d := PartitionStat{ + Device: common.ByteToString([]byte(stat.Mntfromname[:])), + Mountpoint: common.ByteToString([]byte(stat.Mntonname[:])), + Fstype: common.ByteToString([]byte(stat.Fstypename[:])), + Opts: opts, + } + + ret = append(ret, d) + } + + return ret, nil +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + ret := make(map[string]IOCountersStat) + return ret, common.ErrNotImplementedError +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + stat := Statvfs{} + flag := uint64(1) // ST_WAIT/MNT_WAIT, see sys/fstypes.h + + _path, e := unix.BytePtrFromString(path) + if e != nil { + return nil, e + } + + _, _, err := unix.Syscall( + 484, // SYS___statvfs190, see sys/syscall.h + uintptr(unsafe.Pointer(_path)), + uintptr(unsafe.Pointer(&stat)), + uintptr(unsafe.Pointer(&flag)), + ) + if err != 0 { + return nil, err + } + + // frsize is the real block size on NetBSD. See discuss here: https://bugzilla.samba.org/show_bug.cgi?id=11810 + bsize := stat.Frsize + ret := &UsageStat{ + Path: path, + Fstype: getFsType(stat), + Total: (uint64(stat.Blocks) * uint64(bsize)), + Free: (uint64(stat.Bavail) * uint64(bsize)), + InodesTotal: (uint64(stat.Files)), + InodesFree: (uint64(stat.Ffree)), + } + + ret.InodesUsed = (ret.InodesTotal - ret.InodesFree) + ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0 + ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize) + ret.UsedPercent = (float64(ret.Used) / float64(ret.Total)) * 100.0 + + return ret, nil +} + +func getFsType(stat Statvfs) string { + return common.ByteToString(stat.Fstypename[:]) +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_amd64.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_amd64.go new file mode 100644 index 0000000000..c21421cfeb --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_amd64.go @@ -0,0 +1,45 @@ +//go:build netbsd && amd64 +// +build netbsd,amd64 + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs types_netbsd.go + +package disk + +const ( + sizeOfStatvfs = 0xce0 +) + +type ( + Statvfs struct { + Flag uint64 + Bsize uint64 + Frsize uint64 + Iosize uint64 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Bresvd uint64 + Files uint64 + Ffree uint64 + Favail uint64 + Fresvd uint64 + Syncreads uint64 + Syncwrites uint64 + Asyncreads uint64 + Asyncwrites uint64 + Fsidx _Ctype_struct___0 + Fsid uint64 + Namemax uint64 + Owner uint32 + Spare [4]uint64 + Fstypename [32]uint8 + Mntonname [1024]uint8 + Mntfromname [1024]uint8 + Mntfromlabel [1024]uint8 + } +) + +type _Ctype_struct___0 struct { + FsidVal [2]int32 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_arm64.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_arm64.go new file mode 100644 index 0000000000..dfe48f8126 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_netbsd_arm64.go @@ -0,0 +1,45 @@ +//go:build netbsd && arm64 +// +build netbsd,arm64 + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs types_netbsd.go + +package disk + +const ( + sizeOfStatvfs = 0xce0 +) + +type ( + Statvfs struct { + Flag uint64 + Bsize uint64 + Frsize uint64 + Iosize uint64 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Bresvd uint64 + Files uint64 + Ffree uint64 + Favail uint64 + Fresvd uint64 + Syncreads uint64 + Syncwrites uint64 + Asyncreads uint64 + Asyncwrites uint64 + Fsidx _Ctype_struct___0 + Fsid uint64 + Namemax uint64 + Owner uint32 + Spare [4]uint64 + Fstypename [32]uint8 + Mntonname [1024]uint8 + Mntfromname [1024]uint8 + Mntfromlabel [1024]uint8 + } +) + +type _Ctype_struct___0 struct { + FsidVal [2]int32 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd.go new file mode 100644 index 0000000000..81ff23994b --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd.go @@ -0,0 +1,159 @@ +//go:build openbsd +// +build openbsd + +package disk + +import ( + "bytes" + "context" + "encoding/binary" + + "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/unix" +) + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + var ret []PartitionStat + + // get length + count, err := unix.Getfsstat(nil, unix.MNT_WAIT) + if err != nil { + return ret, err + } + + fs := make([]unix.Statfs_t, count) + if _, err = unix.Getfsstat(fs, unix.MNT_WAIT); err != nil { + return ret, err + } + + for _, stat := range fs { + opts := []string{"rw"} + if stat.F_flags&unix.MNT_RDONLY != 0 { + opts = []string{"rw"} + } + if stat.F_flags&unix.MNT_SYNCHRONOUS != 0 { + opts = append(opts, "sync") + } + if stat.F_flags&unix.MNT_NOEXEC != 0 { + opts = append(opts, "noexec") + } + if stat.F_flags&unix.MNT_NOSUID != 0 { + opts = append(opts, "nosuid") + } + if stat.F_flags&unix.MNT_NODEV != 0 { + opts = append(opts, "nodev") + } + if stat.F_flags&unix.MNT_ASYNC != 0 { + opts = append(opts, "async") + } + if stat.F_flags&unix.MNT_SOFTDEP != 0 { + opts = append(opts, "softdep") + } + if stat.F_flags&unix.MNT_NOATIME != 0 { + opts = append(opts, "noatime") + } + if stat.F_flags&unix.MNT_WXALLOWED != 0 { + opts = append(opts, "wxallowed") + } + + d := PartitionStat{ + Device: common.ByteToString(stat.F_mntfromname[:]), + Mountpoint: common.ByteToString(stat.F_mntonname[:]), + Fstype: common.ByteToString(stat.F_fstypename[:]), + Opts: opts, + } + + ret = append(ret, d) + } + + return ret, nil +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + ret := make(map[string]IOCountersStat) + + r, err := unix.SysctlRaw("hw.diskstats") + if err != nil { + return nil, err + } + buf := []byte(r) + length := len(buf) + + count := int(uint64(length) / uint64(sizeOfDiskstats)) + + // parse buf to Diskstats + for i := 0; i < count; i++ { + b := buf[i*sizeOfDiskstats : i*sizeOfDiskstats+sizeOfDiskstats] + d, err := parseDiskstats(b) + if err != nil { + continue + } + name := common.IntToString(d.Name[:]) + + if len(names) > 0 && !common.StringsHas(names, name) { + continue + } + + ds := IOCountersStat{ + ReadCount: d.Rxfer, + WriteCount: d.Wxfer, + ReadBytes: d.Rbytes, + WriteBytes: d.Wbytes, + Name: name, + } + ret[name] = ds + } + + return ret, nil +} + +// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE) + +func parseDiskstats(buf []byte) (Diskstats, error) { + var ds Diskstats + br := bytes.NewReader(buf) + // err := binary.Read(br, binary.LittleEndian, &ds) + err := common.Read(br, binary.LittleEndian, &ds) + if err != nil { + return ds, err + } + + return ds, nil +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + stat := unix.Statfs_t{} + err := unix.Statfs(path, &stat) + if err != nil { + return nil, err + } + bsize := stat.F_bsize + + ret := &UsageStat{ + Path: path, + Fstype: getFsType(stat), + Total: (uint64(stat.F_blocks) * uint64(bsize)), + Free: (uint64(stat.F_bavail) * uint64(bsize)), + InodesTotal: (uint64(stat.F_files)), + InodesFree: (uint64(stat.F_ffree)), + } + + ret.InodesUsed = (ret.InodesTotal - ret.InodesFree) + ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0 + ret.Used = (uint64(stat.F_blocks) - uint64(stat.F_bfree)) * uint64(bsize) + ret.UsedPercent = (float64(ret.Used) / float64(ret.Total)) * 100.0 + + return ret, nil +} + +func getFsType(stat unix.Statfs_t) string { + return common.ByteToString(stat.F_fstypename[:]) +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_386.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_386.go new file mode 100644 index 0000000000..f4c139f5e2 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_386.go @@ -0,0 +1,38 @@ +//go:build openbsd && 386 +// +build openbsd,386 + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs disk/types_openbsd.go + +package disk + +const ( + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfDiskstats = 0x60 +) + +type Diskstats struct { + Name [16]int8 + Busy int32 + Rxfer uint64 + Wxfer uint64 + Seek uint64 + Rbytes uint64 + Wbytes uint64 + Attachtime Timeval + Timestamp Timeval + Time Timeval +} +type Timeval struct { + Sec int64 + Usec int32 +} + +type Diskstat struct{} +type bintime struct{} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_amd64.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_amd64.go new file mode 100644 index 0000000000..c1bd52ef81 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_amd64.go @@ -0,0 +1,36 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs types_openbsd.go + +package disk + +const ( + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfDiskstats = 0x70 +) + +type Diskstats struct { + Name [16]int8 + Busy int32 + Pad_cgo_0 [4]byte + Rxfer uint64 + Wxfer uint64 + Seek uint64 + Rbytes uint64 + Wbytes uint64 + Attachtime Timeval + Timestamp Timeval + Time Timeval +} +type Timeval struct { + Sec int64 + Usec int64 +} + +type Diskstat struct{} +type bintime struct{} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm.go new file mode 100644 index 0000000000..86054a6264 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm.go @@ -0,0 +1,38 @@ +//go:build openbsd && arm +// +build openbsd,arm + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs disk/types_openbsd.go + +package disk + +const ( + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfDiskstats = 0x60 +) + +type Diskstats struct { + Name [16]int8 + Busy int32 + Rxfer uint64 + Wxfer uint64 + Seek uint64 + Rbytes uint64 + Wbytes uint64 + Attachtime Timeval + Timestamp Timeval + Time Timeval +} +type Timeval struct { + Sec int64 + Usec int32 +} + +type Diskstat struct{} +type bintime struct{} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm64.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm64.go new file mode 100644 index 0000000000..ae1cf57e12 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_arm64.go @@ -0,0 +1,38 @@ +//go:build openbsd && arm64 +// +build openbsd,arm64 + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs disk/types_openbsd.go + +package disk + +const ( + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfDiskstats = 0x70 +) + +type Diskstats struct { + Name [16]int8 + Busy int32 + Rxfer uint64 + Wxfer uint64 + Seek uint64 + Rbytes uint64 + Wbytes uint64 + Attachtime Timeval + Timestamp Timeval + Time Timeval +} +type Timeval struct { + Sec int64 + Usec int64 +} + +type Diskstat struct{} +type bintime struct{} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_riscv64.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_riscv64.go new file mode 100644 index 0000000000..8374b94eba --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_openbsd_riscv64.go @@ -0,0 +1,40 @@ +//go:build openbsd && riscv64 +// +build openbsd,riscv64 + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs disk/types_openbsd.go + +package disk + +const ( + devstat_NO_DATA = 0x00 + devstat_READ = 0x01 + devstat_WRITE = 0x02 + devstat_FREE = 0x03 +) + +const ( + sizeOfDiskstats = 0x70 +) + +type ( + Diskstats struct { + Name [16]int8 + Busy int32 + Rxfer uint64 + Wxfer uint64 + Seek uint64 + Rbytes uint64 + Wbytes uint64 + Attachtime Timeval + Timestamp Timeval + Time Timeval + } + Timeval struct { + Sec int64 + Usec int64 + } +) + +type Diskstat struct{} +type bintime struct{} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_solaris.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_solaris.go new file mode 100644 index 0000000000..5d6ea8653a --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_solaris.go @@ -0,0 +1,261 @@ +//go:build solaris +// +build solaris + +package disk + +import ( + "bufio" + "bytes" + "context" + "fmt" + "math" + "os" + "path/filepath" + "regexp" + "runtime" + "strconv" + "strings" + + "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/unix" +) + +const ( + // _DEFAULT_NUM_MOUNTS is set to `cat /etc/mnttab | wc -l` rounded up to the + // nearest power of two. + _DEFAULT_NUM_MOUNTS = 32 + + // _MNTTAB default place to read mount information + _MNTTAB = "/etc/mnttab" +) + +// A blacklist of read-only virtual filesystems. Writable filesystems are of +// operational concern and must not be included in this list. +var fsTypeBlacklist = map[string]struct{}{ + "ctfs": {}, + "dev": {}, + "fd": {}, + "lofs": {}, + "lxproc": {}, + "mntfs": {}, + "objfs": {}, + "proc": {}, +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + ret := make([]PartitionStat, 0, _DEFAULT_NUM_MOUNTS) + + // Scan mnttab(4) + f, err := os.Open(_MNTTAB) + if err != nil { + } + defer func() { + if err == nil { + err = f.Close() + } else { + f.Close() + } + }() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + fields := strings.Split(scanner.Text(), "\t") + + if _, found := fsTypeBlacklist[fields[2]]; found { + continue + } + + ret = append(ret, PartitionStat{ + // NOTE(seanc@): Device isn't exactly accurate: from mnttab(4): "The name + // of the resource that has been mounted." Ideally this value would come + // from Statvfs_t.Fsid but I'm leaving it to the caller to traverse + // unix.Statvfs(). + Device: fields[0], + Mountpoint: fields[1], + Fstype: fields[2], + Opts: strings.Split(fields[3], ","), + }) + } + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("unable to scan %q: %w", _MNTTAB, err) + } + + return ret, err +} + +var kstatSplit = regexp.MustCompile(`[:\s]+`) + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + var issolaris bool + if runtime.GOOS == "illumos" { + issolaris = false + } else { + issolaris = true + } + // check disks instead of zfs pools + filterstr := "/[^zfs]/:::/^nread$|^nwritten$|^reads$|^writes$|^rtime$|^wtime$/" + kstatSysOut, err := invoke.CommandWithContext(ctx, "kstat", "-c", "disk", "-p", filterstr) + if err != nil { + return nil, fmt.Errorf("cannot execute kstat: %w", err) + } + lines := strings.Split(strings.TrimSpace(string(kstatSysOut)), "\n") + if len(lines) == 0 { + return nil, fmt.Errorf("no disk class found") + } + dnamearr := make(map[string]string) + nreadarr := make(map[string]uint64) + nwrittenarr := make(map[string]uint64) + readsarr := make(map[string]uint64) + writesarr := make(map[string]uint64) + rtimearr := make(map[string]uint64) + wtimearr := make(map[string]uint64) + + // in case the name is "/dev/sda1", then convert to "sda1" + for i, name := range names { + names[i] = filepath.Base(name) + } + + for _, line := range lines { + fields := kstatSplit.Split(line, -1) + if len(fields) == 0 { + continue + } + moduleName := fields[0] + instance := fields[1] + dname := fields[2] + + if len(names) > 0 && !common.StringsHas(names, dname) { + continue + } + dnamearr[moduleName+instance] = dname + // fields[3] is the statistic label, fields[4] is the value + switch fields[3] { + case "nread": + nreadarr[moduleName+instance], err = strconv.ParseUint((fields[4]), 10, 64) + if err != nil { + return nil, err + } + case "nwritten": + nwrittenarr[moduleName+instance], err = strconv.ParseUint((fields[4]), 10, 64) + if err != nil { + return nil, err + } + case "reads": + readsarr[moduleName+instance], err = strconv.ParseUint((fields[4]), 10, 64) + if err != nil { + return nil, err + } + case "writes": + writesarr[moduleName+instance], err = strconv.ParseUint((fields[4]), 10, 64) + if err != nil { + return nil, err + } + case "rtime": + if issolaris { + // from sec to milli secs + var frtime float64 + frtime, err = strconv.ParseFloat((fields[4]), 64) + rtimearr[moduleName+instance] = uint64(frtime * 1000) + } else { + // from nano to milli secs + rtimearr[moduleName+instance], err = strconv.ParseUint((fields[4]), 10, 64) + rtimearr[moduleName+instance] = rtimearr[moduleName+instance] / 1000 / 1000 + } + if err != nil { + return nil, err + } + case "wtime": + if issolaris { + // from sec to milli secs + var fwtime float64 + fwtime, err = strconv.ParseFloat((fields[4]), 64) + wtimearr[moduleName+instance] = uint64(fwtime * 1000) + } else { + // from nano to milli secs + wtimearr[moduleName+instance], err = strconv.ParseUint((fields[4]), 10, 64) + wtimearr[moduleName+instance] = wtimearr[moduleName+instance] / 1000 / 1000 + } + if err != nil { + return nil, err + } + } + } + + ret := make(map[string]IOCountersStat, 0) + for k := range dnamearr { + d := IOCountersStat{ + Name: dnamearr[k], + ReadBytes: nreadarr[k], + WriteBytes: nwrittenarr[k], + ReadCount: readsarr[k], + WriteCount: writesarr[k], + ReadTime: rtimearr[k], + WriteTime: wtimearr[k], + } + ret[d.Name] = d + } + return ret, nil +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + statvfs := unix.Statvfs_t{} + if err := unix.Statvfs(path, &statvfs); err != nil { + return nil, fmt.Errorf("unable to call statvfs(2) on %q: %w", path, err) + } + + usageStat := &UsageStat{ + Path: path, + Fstype: common.IntToString(statvfs.Basetype[:]), + Total: statvfs.Blocks * statvfs.Frsize, + Free: statvfs.Bfree * statvfs.Frsize, + Used: (statvfs.Blocks - statvfs.Bfree) * statvfs.Frsize, + + // NOTE: ZFS (and FreeBZSD's UFS2) use dynamic inode/dnode allocation. + // Explicitly return a near-zero value for InodesUsedPercent so that nothing + // attempts to garbage collect based on a lack of available inodes/dnodes. + // Similarly, don't use the zero value to prevent divide-by-zero situations + // and inject a faux near-zero value. Filesystems evolve. Has your + // filesystem evolved? Probably not if you care about the number of + // available inodes. + InodesTotal: 1024.0 * 1024.0, + InodesUsed: 1024.0, + InodesFree: math.MaxUint64, + InodesUsedPercent: (1024.0 / (1024.0 * 1024.0)) * 100.0, + } + + usageStat.UsedPercent = (float64(usageStat.Used) / float64(usageStat.Total)) * 100.0 + + return usageStat, nil +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + out, err := invoke.CommandWithContext(ctx, "cfgadm", "-ls", "select=type(disk),cols=ap_id:info,cols2=,noheadings") + if err != nil { + return "", fmt.Errorf("exec cfgadm: %w", err) + } + + suf := "::" + strings.TrimPrefix(name, "/dev/") + s := bufio.NewScanner(bytes.NewReader(out)) + for s.Scan() { + flds := strings.Fields(s.Text()) + if strings.HasSuffix(flds[0], suf) { + flen := len(flds) + if flen >= 3 { + for i, f := range flds { + if i > 0 && i < flen-1 && f == "SN:" { + return flds[i+1], nil + } + } + } + return "", nil + } + } + if err := s.Err(); err != nil { + return "", err + } + return "", nil +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_unix.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_unix.go new file mode 100644 index 0000000000..1e73524081 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_unix.go @@ -0,0 +1,63 @@ +//go:build freebsd || linux || darwin || (aix && !cgo) +// +build freebsd linux darwin aix,!cgo + +package disk + +import ( + "context" + "strconv" + + "golang.org/x/sys/unix" +) + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + stat := unix.Statfs_t{} + err := unix.Statfs(path, &stat) + if err != nil { + return nil, err + } + bsize := stat.Bsize + + ret := &UsageStat{ + Path: unescapeFstab(path), + Fstype: getFsType(stat), + Total: (uint64(stat.Blocks) * uint64(bsize)), + Free: (uint64(stat.Bavail) * uint64(bsize)), + InodesTotal: (uint64(stat.Files)), + InodesFree: (uint64(stat.Ffree)), + } + + ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize) + + if (ret.Used + ret.Free) == 0 { + ret.UsedPercent = 0 + } else { + // We don't use ret.Total to calculate percent. + // see https://github.com/shirou/gopsutil/issues/562 + ret.UsedPercent = (float64(ret.Used) / float64(ret.Used+ret.Free)) * 100.0 + } + + // if could not get InodesTotal, return empty + if ret.InodesTotal < ret.InodesFree { + return ret, nil + } + + ret.InodesUsed = (ret.InodesTotal - ret.InodesFree) + + if ret.InodesTotal == 0 { + ret.InodesUsedPercent = 0 + } else { + ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0 + } + + return ret, nil +} + +// Unescape escaped octal chars (like space 040, ampersand 046 and backslash 134) to their real value in fstab fields issue#555 +func unescapeFstab(path string) string { + escaped, err := strconv.Unquote(`"` + path + `"`) + if err != nil { + return path + } + return escaped +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/disk_windows.go b/vendor/github.com/shirou/gopsutil/v3/disk/disk_windows.go new file mode 100644 index 0000000000..e17db3e5be --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/disk_windows.go @@ -0,0 +1,241 @@ +//go:build windows +// +build windows + +package disk + +import ( + "bytes" + "context" + "fmt" + "syscall" + "unsafe" + + "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/windows" + "golang.org/x/sys/windows/registry" +) + +var ( + procGetDiskFreeSpaceExW = common.Modkernel32.NewProc("GetDiskFreeSpaceExW") + procGetLogicalDriveStringsW = common.Modkernel32.NewProc("GetLogicalDriveStringsW") + procGetDriveType = common.Modkernel32.NewProc("GetDriveTypeW") + procGetVolumeInformation = common.Modkernel32.NewProc("GetVolumeInformationW") +) + +var ( + fileFileCompression = int64(16) // 0x00000010 + fileReadOnlyVolume = int64(524288) // 0x00080000 +) + +// diskPerformance is an equivalent representation of DISK_PERFORMANCE in the Windows API. +// https://docs.microsoft.com/fr-fr/windows/win32/api/winioctl/ns-winioctl-disk_performance +type diskPerformance struct { + BytesRead int64 + BytesWritten int64 + ReadTime int64 + WriteTime int64 + IdleTime int64 + ReadCount uint32 + WriteCount uint32 + QueueDepth uint32 + SplitCount uint32 + QueryTime int64 + StorageDeviceNumber uint32 + StorageManagerName [8]uint16 + alignmentPadding uint32 // necessary for 32bit support, see https://github.com/elastic/beats/pull/16553 +} + +func init() { + // enable disk performance counters on Windows Server editions (needs to run as admin) + key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Services\PartMgr`, registry.SET_VALUE) + if err == nil { + key.SetDWordValue("EnableCounterForIoctl", 1) + key.Close() + } +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + lpFreeBytesAvailable := int64(0) + lpTotalNumberOfBytes := int64(0) + lpTotalNumberOfFreeBytes := int64(0) + diskret, _, err := procGetDiskFreeSpaceExW.Call( + uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(path))), + uintptr(unsafe.Pointer(&lpFreeBytesAvailable)), + uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)), + uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes))) + if diskret == 0 { + return nil, err + } + ret := &UsageStat{ + Path: path, + Total: uint64(lpTotalNumberOfBytes), + Free: uint64(lpTotalNumberOfFreeBytes), + Used: uint64(lpTotalNumberOfBytes) - uint64(lpTotalNumberOfFreeBytes), + UsedPercent: (float64(lpTotalNumberOfBytes) - float64(lpTotalNumberOfFreeBytes)) / float64(lpTotalNumberOfBytes) * 100, + // InodesTotal: 0, + // InodesFree: 0, + // InodesUsed: 0, + // InodesUsedPercent: 0, + } + return ret, nil +} + +// PartitionsWithContext returns disk partitions. +// Since GetVolumeInformation doesn't have a timeout, this method uses context to set deadline by users. +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + warnings := Warnings{ + Verbose: true, + } + + var errLogicalDrives error + retChan := make(chan PartitionStat) + quitChan := make(chan struct{}) + defer close(quitChan) + + getPartitions := func() { + defer close(retChan) + + lpBuffer := make([]byte, 254) + + diskret, _, err := procGetLogicalDriveStringsW.Call( + uintptr(len(lpBuffer)), + uintptr(unsafe.Pointer(&lpBuffer[0]))) + if diskret == 0 { + errLogicalDrives = err + return + } + for _, v := range lpBuffer { + if v >= 65 && v <= 90 { + path := string(v) + ":" + typepath, _ := windows.UTF16PtrFromString(path) + typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath))) + if typeret == 0 { + err := windows.GetLastError() + warnings.Add(err) + continue + } + // 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 4: DRIVE_REMOTE 5: DRIVE_CDROM + + if typeret == 2 || typeret == 3 || typeret == 4 || typeret == 5 { + lpVolumeNameBuffer := make([]byte, 256) + lpVolumeSerialNumber := int64(0) + lpMaximumComponentLength := int64(0) + lpFileSystemFlags := int64(0) + lpFileSystemNameBuffer := make([]byte, 256) + volpath, _ := windows.UTF16PtrFromString(string(v) + ":/") + driveret, _, err := procGetVolumeInformation.Call( + uintptr(unsafe.Pointer(volpath)), + uintptr(unsafe.Pointer(&lpVolumeNameBuffer[0])), + uintptr(len(lpVolumeNameBuffer)), + uintptr(unsafe.Pointer(&lpVolumeSerialNumber)), + uintptr(unsafe.Pointer(&lpMaximumComponentLength)), + uintptr(unsafe.Pointer(&lpFileSystemFlags)), + uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])), + uintptr(len(lpFileSystemNameBuffer))) + if driveret == 0 { + if typeret == 5 || typeret == 2 { + continue // device is not ready will happen if there is no disk in the drive + } + warnings.Add(err) + continue + } + opts := []string{"rw"} + if lpFileSystemFlags&fileReadOnlyVolume != 0 { + opts = []string{"ro"} + } + if lpFileSystemFlags&fileFileCompression != 0 { + opts = append(opts, "compress") + } + + select { + case retChan <- PartitionStat{ + Mountpoint: path, + Device: path, + Fstype: string(bytes.ReplaceAll(lpFileSystemNameBuffer, []byte("\x00"), []byte(""))), + Opts: opts, + }: + case <-quitChan: + return + } + } + } + } + } + + go getPartitions() + + var ret []PartitionStat + for { + select { + case p, ok := <-retChan: + if !ok { + if errLogicalDrives != nil { + return ret, errLogicalDrives + } + return ret, warnings.Reference() + } + ret = append(ret, p) + case <-ctx.Done(): + return ret, ctx.Err() + } + } +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + // https://github.com/giampaolo/psutil/blob/544e9daa4f66a9f80d7bf6c7886d693ee42f0a13/psutil/arch/windows/disk.c#L83 + drivemap := make(map[string]IOCountersStat, 0) + var diskPerformance diskPerformance + + lpBuffer := make([]uint16, 254) + lpBufferLen, err := windows.GetLogicalDriveStrings(uint32(len(lpBuffer)), &lpBuffer[0]) + if err != nil { + return drivemap, err + } + for _, v := range lpBuffer[:lpBufferLen] { + if 'A' <= v && v <= 'Z' { + path := string(rune(v)) + ":" + typepath, _ := windows.UTF16PtrFromString(path) + typeret := windows.GetDriveType(typepath) + if typeret == 0 { + return drivemap, windows.GetLastError() + } + if typeret != windows.DRIVE_FIXED { + continue + } + szDevice := fmt.Sprintf(`\\.\%s`, path) + const IOCTL_DISK_PERFORMANCE = 0x70020 + h, err := windows.CreateFile(syscall.StringToUTF16Ptr(szDevice), 0, windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE, nil, windows.OPEN_EXISTING, 0, 0) + if err != nil { + if err == windows.ERROR_FILE_NOT_FOUND { + continue + } + return drivemap, err + } + defer windows.CloseHandle(h) + + var diskPerformanceSize uint32 + err = windows.DeviceIoControl(h, IOCTL_DISK_PERFORMANCE, nil, 0, (*byte)(unsafe.Pointer(&diskPerformance)), uint32(unsafe.Sizeof(diskPerformance)), &diskPerformanceSize, nil) + if err != nil { + return drivemap, err + } + drivemap[path] = IOCountersStat{ + ReadBytes: uint64(diskPerformance.BytesRead), + WriteBytes: uint64(diskPerformance.BytesWritten), + ReadCount: uint64(diskPerformance.ReadCount), + WriteCount: uint64(diskPerformance.WriteCount), + ReadTime: uint64(diskPerformance.ReadTime / 10000 / 1000), // convert to ms: https://github.com/giampaolo/psutil/issues/1012 + WriteTime: uint64(diskPerformance.WriteTime / 10000 / 1000), + Name: path, + } + } + } + return drivemap, nil +} + +func SerialNumberWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} + +func LabelWithContext(ctx context.Context, name string) (string, error) { + return "", common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.c b/vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.c new file mode 100644 index 0000000000..8aab04f605 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.c @@ -0,0 +1,129 @@ +// https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.c +#include +#include +#include "iostat_darwin.h" + +#define IOKIT 1 /* to get io_name_t in device_types.h */ + +#include +#include +#include +#include + +#include + +static int getdrivestat(io_registry_entry_t d, DriveStats *stat); +static int fillstat(io_registry_entry_t d, DriveStats *stat); + +int +gopsutil_v3_readdrivestat(DriveStats a[], int n) +{ + CFMutableDictionaryRef match; + io_iterator_t drives; + io_registry_entry_t d; + kern_return_t status; + int na, rv; + + match = IOServiceMatching("IOMedia"); + CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); + status = IOServiceGetMatchingServices(0, match, &drives); + if(status != KERN_SUCCESS) + return -1; + + na = 0; + while(na < n && (d=IOIteratorNext(drives)) > 0){ + rv = getdrivestat(d, &a[na]); + if(rv < 0) + return -1; + if(rv > 0) + na++; + IOObjectRelease(d); + } + IOObjectRelease(drives); + return na; +} + +static int +getdrivestat(io_registry_entry_t d, DriveStats *stat) +{ + io_registry_entry_t parent; + kern_return_t status; + CFDictionaryRef props; + CFStringRef name; + CFNumberRef num; + int rv; + + memset(stat, 0, sizeof *stat); + status = IORegistryEntryGetParentEntry(d, kIOServicePlane, &parent); + if(status != KERN_SUCCESS) + return -1; + if(!IOObjectConformsTo(parent, "IOBlockStorageDriver")){ + IOObjectRelease(parent); + return 0; + } + + status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions); + if(status != KERN_SUCCESS){ + IOObjectRelease(parent); + return -1; + } + name = (CFStringRef)CFDictionaryGetValue(props, CFSTR(kIOBSDNameKey)); + CFStringGetCString(name, stat->name, NAMELEN, CFStringGetSystemEncoding()); + num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaSizeKey)); + CFNumberGetValue(num, kCFNumberSInt64Type, &stat->size); + num = (CFNumberRef)CFDictionaryGetValue(props, CFSTR(kIOMediaPreferredBlockSizeKey)); + CFNumberGetValue(num, kCFNumberSInt64Type, &stat->blocksize); + CFRelease(props); + + rv = fillstat(parent, stat); + IOObjectRelease(parent); + if(rv < 0) + return -1; + return 1; +} + +static struct { + char *key; + size_t off; +} statstab[] = { + {kIOBlockStorageDriverStatisticsBytesReadKey, offsetof(DriveStats, read)}, + {kIOBlockStorageDriverStatisticsBytesWrittenKey, offsetof(DriveStats, written)}, + {kIOBlockStorageDriverStatisticsReadsKey, offsetof(DriveStats, nread)}, + {kIOBlockStorageDriverStatisticsWritesKey, offsetof(DriveStats, nwrite)}, + {kIOBlockStorageDriverStatisticsTotalReadTimeKey, offsetof(DriveStats, readtime)}, + {kIOBlockStorageDriverStatisticsTotalWriteTimeKey, offsetof(DriveStats, writetime)}, + {kIOBlockStorageDriverStatisticsLatentReadTimeKey, offsetof(DriveStats, readlat)}, + {kIOBlockStorageDriverStatisticsLatentWriteTimeKey, offsetof(DriveStats, writelat)}, +}; + +static int +fillstat(io_registry_entry_t d, DriveStats *stat) +{ + CFDictionaryRef props, v; + CFNumberRef num; + kern_return_t status; + typeof(statstab[0]) *bp, *ep; + + status = IORegistryEntryCreateCFProperties(d, (CFMutableDictionaryRef *)&props, kCFAllocatorDefault, kNilOptions); + if(status != KERN_SUCCESS) + return -1; + v = (CFDictionaryRef)CFDictionaryGetValue(props, CFSTR(kIOBlockStorageDriverStatisticsKey)); + if(v == NULL){ + CFRelease(props); + return -1; + } + + ep = &statstab[sizeof(statstab)/sizeof(statstab[0])]; + for(bp = &statstab[0]; bp < ep; bp++){ + CFStringRef s; + + s = CFStringCreateWithCString(kCFAllocatorDefault, bp->key, CFStringGetSystemEncoding()); + num = (CFNumberRef)CFDictionaryGetValue(v, s); + if(num) + CFNumberGetValue(num, kCFNumberSInt64Type, ((char*)stat)+bp->off); + CFRelease(s); + } + + CFRelease(props); + return 0; +} diff --git a/vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.h b/vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.h new file mode 100644 index 0000000000..cb9ec7a0a1 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/disk/iostat_darwin.h @@ -0,0 +1,32 @@ +// https://github.com/lufia/iostat/blob/9f7362b77ad333b26c01c99de52a11bdb650ded2/iostat_darwin.h +typedef struct DriveStats DriveStats; +typedef struct CPUStats CPUStats; + +enum { + NDRIVE = 16, + NAMELEN = 31 +}; + +struct DriveStats { + char name[NAMELEN+1]; + int64_t size; + int64_t blocksize; + + int64_t read; + int64_t written; + int64_t nread; + int64_t nwrite; + int64_t readtime; + int64_t writetime; + int64_t readlat; + int64_t writelat; +}; + +struct CPUStats { + natural_t user; + natural_t nice; + natural_t sys; + natural_t idle; +}; + +extern int gopsutil_v3_readdrivestat(DriveStats a[], int n); diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go new file mode 100644 index 0000000000..5e8d43db83 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go @@ -0,0 +1,637 @@ +package common + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package binary implements simple translation between numbers and byte +// sequences and encoding and decoding of varints. +// +// Numbers are translated by reading and writing fixed-size values. +// A fixed-size value is either a fixed-size arithmetic +// type (int8, uint8, int16, float32, complex64, ...) +// or an array or struct containing only fixed-size values. +// +// The varint functions encode and decode single integer values using +// a variable-length encoding; smaller values require fewer bytes. +// For a specification, see +// http://code.google.com/apis/protocolbuffers/docs/encoding.html. +// +// This package favors simplicity over efficiency. Clients that require +// high-performance serialization, especially for large data structures, +// should look at more advanced solutions such as the encoding/gob +// package or protocol buffers. + +import ( + "errors" + "io" + "math" + "reflect" +) + +// A ByteOrder specifies how to convert byte sequences into +// 16-, 32-, or 64-bit unsigned integers. +type ByteOrder interface { + Uint16([]byte) uint16 + Uint32([]byte) uint32 + Uint64([]byte) uint64 + PutUint16([]byte, uint16) + PutUint32([]byte, uint32) + PutUint64([]byte, uint64) + String() string +} + +// LittleEndian is the little-endian implementation of ByteOrder. +var LittleEndian littleEndian + +// BigEndian is the big-endian implementation of ByteOrder. +var BigEndian bigEndian + +type littleEndian struct{} + +func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 } + +func (littleEndian) PutUint16(b []byte, v uint16) { + b[0] = byte(v) + b[1] = byte(v >> 8) +} + +func (littleEndian) Uint32(b []byte) uint32 { + return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 +} + +func (littleEndian) PutUint32(b []byte, v uint32) { + b[0] = byte(v) + b[1] = byte(v >> 8) + b[2] = byte(v >> 16) + b[3] = byte(v >> 24) +} + +func (littleEndian) Uint64(b []byte) uint64 { + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 +} + +func (littleEndian) PutUint64(b []byte, v uint64) { + b[0] = byte(v) + b[1] = byte(v >> 8) + b[2] = byte(v >> 16) + b[3] = byte(v >> 24) + b[4] = byte(v >> 32) + b[5] = byte(v >> 40) + b[6] = byte(v >> 48) + b[7] = byte(v >> 56) +} + +func (littleEndian) String() string { return "LittleEndian" } + +func (littleEndian) GoString() string { return "binary.LittleEndian" } + +type bigEndian struct{} + +func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 } + +func (bigEndian) PutUint16(b []byte, v uint16) { + b[0] = byte(v >> 8) + b[1] = byte(v) +} + +func (bigEndian) Uint32(b []byte) uint32 { + return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 +} + +func (bigEndian) PutUint32(b []byte, v uint32) { + b[0] = byte(v >> 24) + b[1] = byte(v >> 16) + b[2] = byte(v >> 8) + b[3] = byte(v) +} + +func (bigEndian) Uint64(b []byte) uint64 { + return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | + uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 +} + +func (bigEndian) PutUint64(b []byte, v uint64) { + b[0] = byte(v >> 56) + b[1] = byte(v >> 48) + b[2] = byte(v >> 40) + b[3] = byte(v >> 32) + b[4] = byte(v >> 24) + b[5] = byte(v >> 16) + b[6] = byte(v >> 8) + b[7] = byte(v) +} + +func (bigEndian) String() string { return "BigEndian" } + +func (bigEndian) GoString() string { return "binary.BigEndian" } + +// Read reads structured binary data from r into data. +// Data must be a pointer to a fixed-size value or a slice +// of fixed-size values. +// Bytes read from r are decoded using the specified byte order +// and written to successive fields of the data. +// When reading into structs, the field data for fields with +// blank (_) field names is skipped; i.e., blank field names +// may be used for padding. +// When reading into a struct, all non-blank fields must be exported. +func Read(r io.Reader, order ByteOrder, data interface{}) error { + // Fast path for basic types and slices. + if n := intDataSize(data); n != 0 { + var b [8]byte + var bs []byte + if n > len(b) { + bs = make([]byte, n) + } else { + bs = b[:n] + } + if _, err := io.ReadFull(r, bs); err != nil { + return err + } + switch data := data.(type) { + case *int8: + *data = int8(b[0]) + case *uint8: + *data = b[0] + case *int16: + *data = int16(order.Uint16(bs)) + case *uint16: + *data = order.Uint16(bs) + case *int32: + *data = int32(order.Uint32(bs)) + case *uint32: + *data = order.Uint32(bs) + case *int64: + *data = int64(order.Uint64(bs)) + case *uint64: + *data = order.Uint64(bs) + case []int8: + for i, x := range bs { // Easier to loop over the input for 8-bit values. + data[i] = int8(x) + } + case []uint8: + copy(data, bs) + case []int16: + for i := range data { + data[i] = int16(order.Uint16(bs[2*i:])) + } + case []uint16: + for i := range data { + data[i] = order.Uint16(bs[2*i:]) + } + case []int32: + for i := range data { + data[i] = int32(order.Uint32(bs[4*i:])) + } + case []uint32: + for i := range data { + data[i] = order.Uint32(bs[4*i:]) + } + case []int64: + for i := range data { + data[i] = int64(order.Uint64(bs[8*i:])) + } + case []uint64: + for i := range data { + data[i] = order.Uint64(bs[8*i:]) + } + } + return nil + } + + // Fallback to reflect-based decoding. + v := reflect.ValueOf(data) + size := -1 + switch v.Kind() { + case reflect.Ptr: + v = v.Elem() + size = dataSize(v) + case reflect.Slice: + size = dataSize(v) + } + if size < 0 { + return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String()) + } + d := &decoder{order: order, buf: make([]byte, size)} + if _, err := io.ReadFull(r, d.buf); err != nil { + return err + } + d.value(v) + return nil +} + +// Write writes the binary representation of data into w. +// Data must be a fixed-size value or a slice of fixed-size +// values, or a pointer to such data. +// Bytes written to w are encoded using the specified byte order +// and read from successive fields of the data. +// When writing structs, zero values are written for fields +// with blank (_) field names. +func Write(w io.Writer, order ByteOrder, data interface{}) error { + // Fast path for basic types and slices. + if n := intDataSize(data); n != 0 { + var b [8]byte + var bs []byte + if n > len(b) { + bs = make([]byte, n) + } else { + bs = b[:n] + } + switch v := data.(type) { + case *int8: + bs = b[:1] + b[0] = byte(*v) + case int8: + bs = b[:1] + b[0] = byte(v) + case []int8: + for i, x := range v { + bs[i] = byte(x) + } + case *uint8: + bs = b[:1] + b[0] = *v + case uint8: + bs = b[:1] + b[0] = byte(v) + case []uint8: + bs = v + case *int16: + bs = b[:2] + order.PutUint16(bs, uint16(*v)) + case int16: + bs = b[:2] + order.PutUint16(bs, uint16(v)) + case []int16: + for i, x := range v { + order.PutUint16(bs[2*i:], uint16(x)) + } + case *uint16: + bs = b[:2] + order.PutUint16(bs, *v) + case uint16: + bs = b[:2] + order.PutUint16(bs, v) + case []uint16: + for i, x := range v { + order.PutUint16(bs[2*i:], x) + } + case *int32: + bs = b[:4] + order.PutUint32(bs, uint32(*v)) + case int32: + bs = b[:4] + order.PutUint32(bs, uint32(v)) + case []int32: + for i, x := range v { + order.PutUint32(bs[4*i:], uint32(x)) + } + case *uint32: + bs = b[:4] + order.PutUint32(bs, *v) + case uint32: + bs = b[:4] + order.PutUint32(bs, v) + case []uint32: + for i, x := range v { + order.PutUint32(bs[4*i:], x) + } + case *int64: + bs = b[:8] + order.PutUint64(bs, uint64(*v)) + case int64: + bs = b[:8] + order.PutUint64(bs, uint64(v)) + case []int64: + for i, x := range v { + order.PutUint64(bs[8*i:], uint64(x)) + } + case *uint64: + bs = b[:8] + order.PutUint64(bs, *v) + case uint64: + bs = b[:8] + order.PutUint64(bs, v) + case []uint64: + for i, x := range v { + order.PutUint64(bs[8*i:], x) + } + } + _, err := w.Write(bs) + return err + } + + // Fallback to reflect-based encoding. + v := reflect.Indirect(reflect.ValueOf(data)) + size := dataSize(v) + if size < 0 { + return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String()) + } + buf := make([]byte, size) + e := &encoder{order: order, buf: buf} + e.value(v) + _, err := w.Write(buf) + return err +} + +// Size returns how many bytes Write would generate to encode the value v, which +// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data. +// If v is neither of these, Size returns -1. +func Size(v interface{}) int { + return dataSize(reflect.Indirect(reflect.ValueOf(v))) +} + +// dataSize returns the number of bytes the actual data represented by v occupies in memory. +// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice +// it returns the length of the slice times the element size and does not count the memory +// occupied by the header. If the type of v is not acceptable, dataSize returns -1. +func dataSize(v reflect.Value) int { + if v.Kind() == reflect.Slice { + if s := sizeof(v.Type().Elem()); s >= 0 { + return s * v.Len() + } + return -1 + } + return sizeof(v.Type()) +} + +// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable. +func sizeof(t reflect.Type) int { + switch t.Kind() { + case reflect.Array: + if s := sizeof(t.Elem()); s >= 0 { + return s * t.Len() + } + + case reflect.Struct: + sum := 0 + for i, n := 0, t.NumField(); i < n; i++ { + s := sizeof(t.Field(i).Type) + if s < 0 { + return -1 + } + sum += s + } + return sum + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr: + return int(t.Size()) + } + + return -1 +} + +type coder struct { + order ByteOrder + buf []byte +} + +type ( + decoder coder + encoder coder +) + +func (d *decoder) uint8() uint8 { + x := d.buf[0] + d.buf = d.buf[1:] + return x +} + +func (e *encoder) uint8(x uint8) { + e.buf[0] = x + e.buf = e.buf[1:] +} + +func (d *decoder) uint16() uint16 { + x := d.order.Uint16(d.buf[0:2]) + d.buf = d.buf[2:] + return x +} + +func (e *encoder) uint16(x uint16) { + e.order.PutUint16(e.buf[0:2], x) + e.buf = e.buf[2:] +} + +func (d *decoder) uint32() uint32 { + x := d.order.Uint32(d.buf[0:4]) + d.buf = d.buf[4:] + return x +} + +func (e *encoder) uint32(x uint32) { + e.order.PutUint32(e.buf[0:4], x) + e.buf = e.buf[4:] +} + +func (d *decoder) uint64() uint64 { + x := d.order.Uint64(d.buf[0:8]) + d.buf = d.buf[8:] + return x +} + +func (e *encoder) uint64(x uint64) { + e.order.PutUint64(e.buf[0:8], x) + e.buf = e.buf[8:] +} + +func (d *decoder) int8() int8 { return int8(d.uint8()) } + +func (e *encoder) int8(x int8) { e.uint8(uint8(x)) } + +func (d *decoder) int16() int16 { return int16(d.uint16()) } + +func (e *encoder) int16(x int16) { e.uint16(uint16(x)) } + +func (d *decoder) int32() int32 { return int32(d.uint32()) } + +func (e *encoder) int32(x int32) { e.uint32(uint32(x)) } + +func (d *decoder) int64() int64 { return int64(d.uint64()) } + +func (e *encoder) int64(x int64) { e.uint64(uint64(x)) } + +func (d *decoder) value(v reflect.Value) { + switch v.Kind() { + case reflect.Array: + l := v.Len() + for i := 0; i < l; i++ { + d.value(v.Index(i)) + } + + case reflect.Struct: + t := v.Type() + l := v.NumField() + for i := 0; i < l; i++ { + // Note: Calling v.CanSet() below is an optimization. + // It would be sufficient to check the field name, + // but creating the StructField info for each field is + // costly (run "go test -bench=ReadStruct" and compare + // results when making changes to this code). + if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { + d.value(v) + } else { + d.skip(v) + } + } + + case reflect.Slice: + l := v.Len() + for i := 0; i < l; i++ { + d.value(v.Index(i)) + } + + case reflect.Int8: + v.SetInt(int64(d.int8())) + case reflect.Int16: + v.SetInt(int64(d.int16())) + case reflect.Int32: + v.SetInt(int64(d.int32())) + case reflect.Int64: + v.SetInt(d.int64()) + + case reflect.Uint8: + v.SetUint(uint64(d.uint8())) + case reflect.Uint16: + v.SetUint(uint64(d.uint16())) + case reflect.Uint32: + v.SetUint(uint64(d.uint32())) + case reflect.Uint64: + v.SetUint(d.uint64()) + + case reflect.Float32: + v.SetFloat(float64(math.Float32frombits(d.uint32()))) + case reflect.Float64: + v.SetFloat(math.Float64frombits(d.uint64())) + + case reflect.Complex64: + v.SetComplex(complex( + float64(math.Float32frombits(d.uint32())), + float64(math.Float32frombits(d.uint32())), + )) + case reflect.Complex128: + v.SetComplex(complex( + math.Float64frombits(d.uint64()), + math.Float64frombits(d.uint64()), + )) + } +} + +func (e *encoder) value(v reflect.Value) { + switch v.Kind() { + case reflect.Array: + l := v.Len() + for i := 0; i < l; i++ { + e.value(v.Index(i)) + } + + case reflect.Struct: + t := v.Type() + l := v.NumField() + for i := 0; i < l; i++ { + // see comment for corresponding code in decoder.value() + if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" { + e.value(v) + } else { + e.skip(v) + } + } + + case reflect.Slice: + l := v.Len() + for i := 0; i < l; i++ { + e.value(v.Index(i)) + } + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + switch v.Type().Kind() { + case reflect.Int8: + e.int8(int8(v.Int())) + case reflect.Int16: + e.int16(int16(v.Int())) + case reflect.Int32: + e.int32(int32(v.Int())) + case reflect.Int64: + e.int64(v.Int()) + } + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + switch v.Type().Kind() { + case reflect.Uint8: + e.uint8(uint8(v.Uint())) + case reflect.Uint16: + e.uint16(uint16(v.Uint())) + case reflect.Uint32: + e.uint32(uint32(v.Uint())) + case reflect.Uint64: + e.uint64(v.Uint()) + } + + case reflect.Float32, reflect.Float64: + switch v.Type().Kind() { + case reflect.Float32: + e.uint32(math.Float32bits(float32(v.Float()))) + case reflect.Float64: + e.uint64(math.Float64bits(v.Float())) + } + + case reflect.Complex64, reflect.Complex128: + switch v.Type().Kind() { + case reflect.Complex64: + x := v.Complex() + e.uint32(math.Float32bits(float32(real(x)))) + e.uint32(math.Float32bits(float32(imag(x)))) + case reflect.Complex128: + x := v.Complex() + e.uint64(math.Float64bits(real(x))) + e.uint64(math.Float64bits(imag(x))) + } + } +} + +func (d *decoder) skip(v reflect.Value) { + d.buf = d.buf[dataSize(v):] +} + +func (e *encoder) skip(v reflect.Value) { + n := dataSize(v) + for i := range e.buf[0:n] { + e.buf[i] = 0 + } + e.buf = e.buf[n:] +} + +// intDataSize returns the size of the data required to represent the data when encoded. +// It returns zero if the type cannot be implemented by the fast path in Read or Write. +func intDataSize(data interface{}) int { + switch data := data.(type) { + case int8, *int8, *uint8: + return 1 + case []int8: + return len(data) + case []uint8: + return len(data) + case int16, *int16, *uint16: + return 2 + case []int16: + return 2 * len(data) + case []uint16: + return 2 * len(data) + case int32, *int32, *uint32: + return 4 + case []int32: + return 4 * len(data) + case []uint32: + return 4 * len(data) + case int64, *int64, *uint64: + return 8 + case []int64: + return 8 * len(data) + case []uint64: + return 8 * len(data) + } + return 0 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common.go new file mode 100644 index 0000000000..5e25e507b4 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common.go @@ -0,0 +1,464 @@ +package common + +// +// gopsutil is a port of psutil(http://pythonhosted.org/psutil/). +// This covers these architectures. +// - linux (amd64, arm) +// - freebsd (amd64) +// - windows (amd64) + +import ( + "bufio" + "bytes" + "context" + "errors" + "fmt" + "io" + "net/url" + "os" + "os/exec" + "path" + "path/filepath" + "reflect" + "runtime" + "strconv" + "strings" + "time" + + "github.com/shirou/gopsutil/v3/common" +) + +var ( + Timeout = 3 * time.Second + ErrTimeout = errors.New("command timed out") +) + +type Invoker interface { + Command(string, ...string) ([]byte, error) + CommandWithContext(context.Context, string, ...string) ([]byte, error) +} + +type Invoke struct{} + +func (i Invoke) Command(name string, arg ...string) ([]byte, error) { + ctx, cancel := context.WithTimeout(context.Background(), Timeout) + defer cancel() + return i.CommandWithContext(ctx, name, arg...) +} + +func (i Invoke) CommandWithContext(ctx context.Context, name string, arg ...string) ([]byte, error) { + cmd := exec.CommandContext(ctx, name, arg...) + + var buf bytes.Buffer + cmd.Stdout = &buf + cmd.Stderr = &buf + + if err := cmd.Start(); err != nil { + return buf.Bytes(), err + } + + if err := cmd.Wait(); err != nil { + return buf.Bytes(), err + } + + return buf.Bytes(), nil +} + +type FakeInvoke struct { + Suffix string // Suffix species expected file name suffix such as "fail" + Error error // If Error specified, return the error. +} + +// Command in FakeInvoke returns from expected file if exists. +func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) { + if i.Error != nil { + return []byte{}, i.Error + } + + arch := runtime.GOOS + + commandName := filepath.Base(name) + + fname := strings.Join(append([]string{commandName}, arg...), "") + fname = url.QueryEscape(fname) + fpath := path.Join("testdata", arch, fname) + if i.Suffix != "" { + fpath += "_" + i.Suffix + } + if PathExists(fpath) { + return os.ReadFile(fpath) + } + return []byte{}, fmt.Errorf("could not find testdata: %s", fpath) +} + +func (i FakeInvoke) CommandWithContext(ctx context.Context, name string, arg ...string) ([]byte, error) { + return i.Command(name, arg...) +} + +var ErrNotImplementedError = errors.New("not implemented yet") + +// ReadFile reads contents from a file +func ReadFile(filename string) (string, error) { + content, err := os.ReadFile(filename) + if err != nil { + return "", err + } + + return string(content), nil +} + +// ReadLines reads contents from a file and splits them by new lines. +// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1). +func ReadLines(filename string) ([]string, error) { + return ReadLinesOffsetN(filename, 0, -1) +} + +// ReadLine reads a file and returns the first occurrence of a line that is prefixed with prefix. +func ReadLine(filename string, prefix string) (string, error) { + f, err := os.Open(filename) + if err != nil { + return "", err + } + defer f.Close() + r := bufio.NewReader(f) + for { + line, err := r.ReadString('\n') + if err != nil { + if err == io.EOF { + break + } + return "", err + } + if strings.HasPrefix(line, prefix) { + return line, nil + } + } + + return "", nil +} + +// ReadLinesOffsetN reads contents from file and splits them by new line. +// The offset tells at which line number to start. +// The count determines the number of lines to read (starting from offset): +// n >= 0: at most n lines +// n < 0: whole file +func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) { + f, err := os.Open(filename) + if err != nil { + return []string{""}, err + } + defer f.Close() + + var ret []string + + r := bufio.NewReader(f) + for i := 0; i < n+int(offset) || n < 0; i++ { + line, err := r.ReadString('\n') + if err != nil { + if err == io.EOF && len(line) > 0 { + ret = append(ret, strings.Trim(line, "\n")) + } + break + } + if i < int(offset) { + continue + } + ret = append(ret, strings.Trim(line, "\n")) + } + + return ret, nil +} + +func IntToString(orig []int8) string { + ret := make([]byte, len(orig)) + size := -1 + for i, o := range orig { + if o == 0 { + size = i + break + } + ret[i] = byte(o) + } + if size == -1 { + size = len(orig) + } + + return string(ret[0:size]) +} + +func UintToString(orig []uint8) string { + ret := make([]byte, len(orig)) + size := -1 + for i, o := range orig { + if o == 0 { + size = i + break + } + ret[i] = byte(o) + } + if size == -1 { + size = len(orig) + } + + return string(ret[0:size]) +} + +func ByteToString(orig []byte) string { + n := -1 + l := -1 + for i, b := range orig { + // skip left side null + if l == -1 && b == 0 { + continue + } + if l == -1 { + l = i + } + + if b == 0 { + break + } + n = i + 1 + } + if n == -1 { + return string(orig) + } + return string(orig[l:n]) +} + +// ReadInts reads contents from single line file and returns them as []int32. +func ReadInts(filename string) ([]int64, error) { + f, err := os.Open(filename) + if err != nil { + return []int64{}, err + } + defer f.Close() + + var ret []int64 + + r := bufio.NewReader(f) + + // The int files that this is concerned with should only be one liners. + line, err := r.ReadString('\n') + if err != nil { + return []int64{}, err + } + + i, err := strconv.ParseInt(strings.Trim(line, "\n"), 10, 32) + if err != nil { + return []int64{}, err + } + ret = append(ret, i) + + return ret, nil +} + +// Parse Hex to uint32 without error +func HexToUint32(hex string) uint32 { + vv, _ := strconv.ParseUint(hex, 16, 32) + return uint32(vv) +} + +// Parse to int32 without error +func mustParseInt32(val string) int32 { + vv, _ := strconv.ParseInt(val, 10, 32) + return int32(vv) +} + +// Parse to uint64 without error +func mustParseUint64(val string) uint64 { + vv, _ := strconv.ParseInt(val, 10, 64) + return uint64(vv) +} + +// Parse to Float64 without error +func mustParseFloat64(val string) float64 { + vv, _ := strconv.ParseFloat(val, 64) + return vv +} + +// StringsHas checks the target string slice contains src or not +func StringsHas(target []string, src string) bool { + for _, t := range target { + if strings.TrimSpace(t) == src { + return true + } + } + return false +} + +// StringsContains checks the src in any string of the target string slice +func StringsContains(target []string, src string) bool { + for _, t := range target { + if strings.Contains(t, src) { + return true + } + } + return false +} + +// IntContains checks the src in any int of the target int slice. +func IntContains(target []int, src int) bool { + for _, t := range target { + if src == t { + return true + } + } + return false +} + +// get struct attributes. +// This method is used only for debugging platform dependent code. +func attributes(m interface{}) map[string]reflect.Type { + typ := reflect.TypeOf(m) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + + attrs := make(map[string]reflect.Type) + if typ.Kind() != reflect.Struct { + return nil + } + + for i := 0; i < typ.NumField(); i++ { + p := typ.Field(i) + if !p.Anonymous { + attrs[p.Name] = p.Type + } + } + + return attrs +} + +func PathExists(filename string) bool { + if _, err := os.Stat(filename); err == nil { + return true + } + return false +} + +// PathExistsWithContents returns the filename exists and it is not empty +func PathExistsWithContents(filename string) bool { + info, err := os.Stat(filename) + if err != nil { + return false + } + return info.Size() > 4 && !info.IsDir() // at least 4 bytes +} + +// GetEnvWithContext retrieves the environment variable key. If it does not exist it returns the default. +// The context may optionally contain a map superseding os.EnvKey. +func GetEnvWithContext(ctx context.Context, key string, dfault string, combineWith ...string) string { + var value string + if env, ok := ctx.Value(common.EnvKey).(common.EnvMap); ok { + value = env[common.EnvKeyType(key)] + } + if value == "" { + value = os.Getenv(key) + } + if value == "" { + value = dfault + } + + return combine(value, combineWith) +} + +// GetEnv retrieves the environment variable key. If it does not exist it returns the default. +func GetEnv(key string, dfault string, combineWith ...string) string { + value := os.Getenv(key) + if value == "" { + value = dfault + } + + return combine(value, combineWith) +} + +func combine(value string, combineWith []string) string { + switch len(combineWith) { + case 0: + return value + case 1: + return filepath.Join(value, combineWith[0]) + default: + all := make([]string, len(combineWith)+1) + all[0] = value + copy(all[1:], combineWith) + return filepath.Join(all...) + } +} + +func HostProc(combineWith ...string) string { + return GetEnv("HOST_PROC", "/proc", combineWith...) +} + +func HostSys(combineWith ...string) string { + return GetEnv("HOST_SYS", "/sys", combineWith...) +} + +func HostEtc(combineWith ...string) string { + return GetEnv("HOST_ETC", "/etc", combineWith...) +} + +func HostVar(combineWith ...string) string { + return GetEnv("HOST_VAR", "/var", combineWith...) +} + +func HostRun(combineWith ...string) string { + return GetEnv("HOST_RUN", "/run", combineWith...) +} + +func HostDev(combineWith ...string) string { + return GetEnv("HOST_DEV", "/dev", combineWith...) +} + +func HostRoot(combineWith ...string) string { + return GetEnv("HOST_ROOT", "/", combineWith...) +} + +func HostProcWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_PROC", "/proc", combineWith...) +} + +func HostProcMountInfoWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_PROC_MOUNTINFO", "", combineWith...) +} + +func HostSysWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_SYS", "/sys", combineWith...) +} + +func HostEtcWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_ETC", "/etc", combineWith...) +} + +func HostVarWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_VAR", "/var", combineWith...) +} + +func HostRunWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_RUN", "/run", combineWith...) +} + +func HostDevWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_DEV", "/dev", combineWith...) +} + +func HostRootWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_ROOT", "/", combineWith...) +} + +// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running +// sysctl commands (see DoSysctrl). +func getSysctrlEnv(env []string) []string { + foundLC := false + for i, line := range env { + if strings.HasPrefix(line, "LC_ALL") { + env[i] = "LC_ALL=C" + foundLC = true + } + } + if !foundLC { + env = append(env, "LC_ALL=C") + } + return env +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_darwin.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_darwin.go new file mode 100644 index 0000000000..f1a7845977 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_darwin.go @@ -0,0 +1,66 @@ +//go:build darwin +// +build darwin + +package common + +import ( + "context" + "os" + "os/exec" + "strings" + "unsafe" + + "golang.org/x/sys/unix" +) + +func DoSysctrlWithContext(ctx context.Context, mib string) ([]string, error) { + cmd := exec.CommandContext(ctx, "sysctl", "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() + if err != nil { + return []string{}, err + } + v := strings.Replace(string(out), "{ ", "", 1) + v = strings.Replace(string(v), " }", "", 1) + values := strings.Fields(string(v)) + + return values, nil +} + +func CallSyscall(mib []int32) ([]byte, uint64, error) { + miblen := uint64(len(mib)) + + // get required buffer size + length := uint64(0) + _, _, err := unix.Syscall6( + 202, // unix.SYS___SYSCTL https://github.com/golang/sys/blob/76b94024e4b621e672466e8db3d7f084e7ddcad2/unix/zsysnum_darwin_amd64.go#L146 + uintptr(unsafe.Pointer(&mib[0])), + uintptr(miblen), + 0, + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + var b []byte + return b, length, err + } + if length == 0 { + var b []byte + return b, length, err + } + // get proc info itself + buf := make([]byte, length) + _, _, err = unix.Syscall6( + 202, // unix.SYS___SYSCTL https://github.com/golang/sys/blob/76b94024e4b621e672466e8db3d7f084e7ddcad2/unix/zsysnum_darwin_amd64.go#L146 + uintptr(unsafe.Pointer(&mib[0])), + uintptr(miblen), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + return buf, length, err + } + + return buf, length, nil +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_freebsd.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_freebsd.go new file mode 100644 index 0000000000..f590e2e67e --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_freebsd.go @@ -0,0 +1,82 @@ +//go:build freebsd || openbsd +// +build freebsd openbsd + +package common + +import ( + "fmt" + "os" + "os/exec" + "strings" + "unsafe" + + "golang.org/x/sys/unix" +) + +func SysctlUint(mib string) (uint64, error) { + buf, err := unix.SysctlRaw(mib) + if err != nil { + return 0, err + } + if len(buf) == 8 { // 64 bit + return *(*uint64)(unsafe.Pointer(&buf[0])), nil + } + if len(buf) == 4 { // 32bit + t := *(*uint32)(unsafe.Pointer(&buf[0])) + return uint64(t), nil + } + return 0, fmt.Errorf("unexpected size: %s, %d", mib, len(buf)) +} + +func DoSysctrl(mib string) ([]string, error) { + cmd := exec.Command("sysctl", "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() + if err != nil { + return []string{}, err + } + v := strings.Replace(string(out), "{ ", "", 1) + v = strings.Replace(string(v), " }", "", 1) + values := strings.Fields(string(v)) + + return values, nil +} + +func CallSyscall(mib []int32) ([]byte, uint64, error) { + mibptr := unsafe.Pointer(&mib[0]) + miblen := uint64(len(mib)) + + // get required buffer size + length := uint64(0) + _, _, err := unix.Syscall6( + unix.SYS___SYSCTL, + uintptr(mibptr), + uintptr(miblen), + 0, + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + var b []byte + return b, length, err + } + if length == 0 { + var b []byte + return b, length, err + } + // get proc info itself + buf := make([]byte, length) + _, _, err = unix.Syscall6( + unix.SYS___SYSCTL, + uintptr(mibptr), + uintptr(miblen), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + return buf, length, err + } + + return buf, length, nil +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go new file mode 100644 index 0000000000..a429e16a2c --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go @@ -0,0 +1,353 @@ +//go:build linux +// +build linux + +package common + +import ( + "context" + "fmt" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "sync" + "sync/atomic" + "syscall" + "time" +) + +// cachedBootTime must be accessed via atomic.Load/StoreUint64 +var cachedBootTime uint64 + +func DoSysctrl(mib string) ([]string, error) { + cmd := exec.Command("sysctl", "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() + if err != nil { + return []string{}, err + } + v := strings.Replace(string(out), "{ ", "", 1) + v = strings.Replace(string(v), " }", "", 1) + values := strings.Fields(string(v)) + + return values, nil +} + +func NumProcs() (uint64, error) { + return NumProcsWithContext(context.Background()) +} + +func NumProcsWithContext(ctx context.Context) (uint64, error) { + f, err := os.Open(HostProcWithContext(ctx)) + if err != nil { + return 0, err + } + defer f.Close() + + list, err := f.Readdirnames(-1) + if err != nil { + return 0, err + } + var cnt uint64 + + for _, v := range list { + if _, err = strconv.ParseUint(v, 10, 64); err == nil { + cnt++ + } + } + + return cnt, nil +} + +func BootTimeWithContext(ctx context.Context, enableCache bool) (uint64, error) { + if enableCache { + t := atomic.LoadUint64(&cachedBootTime) + if t != 0 { + return t, nil + } + } + + system, role, err := VirtualizationWithContext(ctx) + if err != nil { + return 0, err + } + + useStatFile := true + if system == "lxc" && role == "guest" { + // if lxc, /proc/uptime is used. + useStatFile = false + } else if system == "docker" && role == "guest" { + // also docker, guest + useStatFile = false + } + + if useStatFile { + t, err := readBootTimeStat(ctx) + if err != nil { + return 0, err + } + if enableCache { + atomic.StoreUint64(&cachedBootTime, t) + } + } + + filename := HostProcWithContext(ctx, "uptime") + lines, err := ReadLines(filename) + if err != nil { + return handleBootTimeFileReadErr(err) + } + if len(lines) != 1 { + return 0, fmt.Errorf("wrong uptime format") + } + f := strings.Fields(lines[0]) + b, err := strconv.ParseFloat(f[0], 64) + if err != nil { + return 0, err + } + currentTime := float64(time.Now().UnixNano()) / float64(time.Second) + t := currentTime - b + + if enableCache { + atomic.StoreUint64(&cachedBootTime, uint64(t)) + } + + return uint64(t), nil +} + +func handleBootTimeFileReadErr(err error) (uint64, error) { + if os.IsPermission(err) { + var info syscall.Sysinfo_t + err := syscall.Sysinfo(&info) + if err != nil { + return 0, err + } + + currentTime := time.Now().UnixNano() / int64(time.Second) + t := currentTime - int64(info.Uptime) + return uint64(t), nil + } + return 0, err +} + +func readBootTimeStat(ctx context.Context) (uint64, error) { + filename := HostProcWithContext(ctx, "stat") + line, err := ReadLine(filename, "btime") + if err != nil { + return handleBootTimeFileReadErr(err) + } + if strings.HasPrefix(line, "btime") { + f := strings.Fields(line) + if len(f) != 2 { + return 0, fmt.Errorf("wrong btime format") + } + b, err := strconv.ParseInt(f[1], 10, 64) + if err != nil { + return 0, err + } + t := uint64(b) + return t, nil + } + return 0, fmt.Errorf("could not find btime") +} + +func Virtualization() (string, string, error) { + return VirtualizationWithContext(context.Background()) +} + +// required variables for concurrency safe virtualization caching +var ( + cachedVirtMap map[string]string + cachedVirtMutex sync.RWMutex + cachedVirtOnce sync.Once +) + +func VirtualizationWithContext(ctx context.Context) (string, string, error) { + var system, role string + + // if cached already, return from cache + cachedVirtMutex.RLock() // unlock won't be deferred so concurrent reads don't wait for long + if cachedVirtMap != nil { + cachedSystem, cachedRole := cachedVirtMap["system"], cachedVirtMap["role"] + cachedVirtMutex.RUnlock() + return cachedSystem, cachedRole, nil + } + cachedVirtMutex.RUnlock() + + filename := HostProcWithContext(ctx, "xen") + if PathExists(filename) { + system = "xen" + role = "guest" // assume guest + + if PathExists(filepath.Join(filename, "capabilities")) { + contents, err := ReadLines(filepath.Join(filename, "capabilities")) + if err == nil { + if StringsContains(contents, "control_d") { + role = "host" + } + } + } + } + + filename = HostProcWithContext(ctx, "modules") + if PathExists(filename) { + contents, err := ReadLines(filename) + if err == nil { + if StringsContains(contents, "kvm") { + system = "kvm" + role = "host" + } else if StringsContains(contents, "hv_util") { + system = "hyperv" + role = "guest" + } else if StringsContains(contents, "vboxdrv") { + system = "vbox" + role = "host" + } else if StringsContains(contents, "vboxguest") { + system = "vbox" + role = "guest" + } else if StringsContains(contents, "vmware") { + system = "vmware" + role = "guest" + } + } + } + + filename = HostProcWithContext(ctx, "cpuinfo") + if PathExists(filename) { + contents, err := ReadLines(filename) + if err == nil { + if StringsContains(contents, "QEMU Virtual CPU") || + StringsContains(contents, "Common KVM processor") || + StringsContains(contents, "Common 32-bit KVM processor") { + system = "kvm" + role = "guest" + } + } + } + + filename = HostProcWithContext(ctx, "bus/pci/devices") + if PathExists(filename) { + contents, err := ReadLines(filename) + if err == nil { + if StringsContains(contents, "virtio-pci") { + role = "guest" + } + } + } + + filename = HostProcWithContext(ctx) + if PathExists(filepath.Join(filename, "bc", "0")) { + system = "openvz" + role = "host" + } else if PathExists(filepath.Join(filename, "vz")) { + system = "openvz" + role = "guest" + } + + // not use dmidecode because it requires root + if PathExists(filepath.Join(filename, "self", "status")) { + contents, err := ReadLines(filepath.Join(filename, "self", "status")) + if err == nil { + if StringsContains(contents, "s_context:") || + StringsContains(contents, "VxID:") { + system = "linux-vserver" + } + // TODO: guest or host + } + } + + if PathExists(filepath.Join(filename, "1", "environ")) { + contents, err := ReadFile(filepath.Join(filename, "1", "environ")) + + if err == nil { + if strings.Contains(contents, "container=lxc") { + system = "lxc" + role = "guest" + } + } + } + + if PathExists(filepath.Join(filename, "self", "cgroup")) { + contents, err := ReadLines(filepath.Join(filename, "self", "cgroup")) + if err == nil { + if StringsContains(contents, "lxc") { + system = "lxc" + role = "guest" + } else if StringsContains(contents, "docker") { + system = "docker" + role = "guest" + } else if StringsContains(contents, "machine-rkt") { + system = "rkt" + role = "guest" + } else if PathExists("/usr/bin/lxc-version") { + system = "lxc" + role = "host" + } + } + } + + if PathExists(HostEtcWithContext(ctx, "os-release")) { + p, _, err := GetOSReleaseWithContext(ctx) + if err == nil && p == "coreos" { + system = "rkt" // Is it true? + role = "host" + } + } + + if PathExists(HostRootWithContext(ctx, ".dockerenv")) { + system = "docker" + role = "guest" + } + + // before returning for the first time, cache the system and role + cachedVirtOnce.Do(func() { + cachedVirtMutex.Lock() + defer cachedVirtMutex.Unlock() + cachedVirtMap = map[string]string{ + "system": system, + "role": role, + } + }) + + return system, role, nil +} + +func GetOSRelease() (platform string, version string, err error) { + return GetOSReleaseWithContext(context.Background()) +} + +func GetOSReleaseWithContext(ctx context.Context) (platform string, version string, err error) { + contents, err := ReadLines(HostEtcWithContext(ctx, "os-release")) + if err != nil { + return "", "", nil // return empty + } + for _, line := range contents { + field := strings.Split(line, "=") + if len(field) < 2 { + continue + } + switch field[0] { + case "ID": // use ID for lowercase + platform = trimQuotes(field[1]) + case "VERSION_ID": + version = trimQuotes(field[1]) + } + } + + // cleanup amazon ID + if platform == "amzn" { + platform = "amazon" + } + + return platform, version, nil +} + +// Remove quotes of the source string +func trimQuotes(s string) string { + if len(s) >= 2 { + if s[0] == '"' && s[len(s)-1] == '"' { + return s[1 : len(s)-1] + } + } + return s +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_netbsd.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_netbsd.go new file mode 100644 index 0000000000..efbc710a5e --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_netbsd.go @@ -0,0 +1,66 @@ +//go:build netbsd +// +build netbsd + +package common + +import ( + "os" + "os/exec" + "strings" + "unsafe" + + "golang.org/x/sys/unix" +) + +func DoSysctrl(mib string) ([]string, error) { + cmd := exec.Command("sysctl", "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() + if err != nil { + return []string{}, err + } + v := strings.Replace(string(out), "{ ", "", 1) + v = strings.Replace(string(v), " }", "", 1) + values := strings.Fields(string(v)) + + return values, nil +} + +func CallSyscall(mib []int32) ([]byte, uint64, error) { + mibptr := unsafe.Pointer(&mib[0]) + miblen := uint64(len(mib)) + + // get required buffer size + length := uint64(0) + _, _, err := unix.Syscall6( + unix.SYS___SYSCTL, + uintptr(mibptr), + uintptr(miblen), + 0, + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + var b []byte + return b, length, err + } + if length == 0 { + var b []byte + return b, length, err + } + // get proc info itself + buf := make([]byte, length) + _, _, err = unix.Syscall6( + unix.SYS___SYSCTL, + uintptr(mibptr), + uintptr(miblen), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + return buf, length, err + } + + return buf, length, nil +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_openbsd.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_openbsd.go new file mode 100644 index 0000000000..58d76f334e --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_openbsd.go @@ -0,0 +1,66 @@ +//go:build openbsd +// +build openbsd + +package common + +import ( + "os" + "os/exec" + "strings" + "unsafe" + + "golang.org/x/sys/unix" +) + +func DoSysctrl(mib string) ([]string, error) { + cmd := exec.Command("sysctl", "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() + if err != nil { + return []string{}, err + } + v := strings.Replace(string(out), "{ ", "", 1) + v = strings.Replace(string(v), " }", "", 1) + values := strings.Fields(string(v)) + + return values, nil +} + +func CallSyscall(mib []int32) ([]byte, uint64, error) { + mibptr := unsafe.Pointer(&mib[0]) + miblen := uint64(len(mib)) + + // get required buffer size + length := uint64(0) + _, _, err := unix.Syscall6( + unix.SYS___SYSCTL, + uintptr(mibptr), + uintptr(miblen), + 0, + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + var b []byte + return b, length, err + } + if length == 0 { + var b []byte + return b, length, err + } + // get proc info itself + buf := make([]byte, length) + _, _, err = unix.Syscall6( + unix.SYS___SYSCTL, + uintptr(mibptr), + uintptr(miblen), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&length)), + 0, + 0) + if err != 0 { + return buf, length, err + } + + return buf, length, nil +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_unix.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_unix.go new file mode 100644 index 0000000000..4af7e5c2aa --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_unix.go @@ -0,0 +1,62 @@ +//go:build linux || freebsd || darwin || openbsd +// +build linux freebsd darwin openbsd + +package common + +import ( + "context" + "errors" + "os/exec" + "strconv" + "strings" +) + +func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args ...string) ([]string, error) { + var cmd []string + if pid == 0 { // will get from all processes. + cmd = []string{"-a", "-n", "-P"} + } else { + cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))} + } + cmd = append(cmd, args...) + out, err := invoke.CommandWithContext(ctx, "lsof", cmd...) + if err != nil { + if errors.Is(err, exec.ErrNotFound) { + return []string{}, err + } + // if no pid found, lsof returns code 1. + if err.Error() == "exit status 1" && len(out) == 0 { + return []string{}, nil + } + } + lines := strings.Split(string(out), "\n") + + var ret []string + for _, l := range lines[1:] { + if len(l) == 0 { + continue + } + ret = append(ret, l) + } + return ret, nil +} + +func CallPgrepWithContext(ctx context.Context, invoke Invoker, pid int32) ([]int32, error) { + out, err := invoke.CommandWithContext(ctx, "pgrep", "-P", strconv.Itoa(int(pid))) + if err != nil { + return []int32{}, err + } + lines := strings.Split(string(out), "\n") + ret := make([]int32, 0, len(lines)) + for _, l := range lines { + if len(l) == 0 { + continue + } + i, err := strconv.ParseInt(l, 10, 32) + if err != nil { + continue + } + ret = append(ret, int32(i)) + } + return ret, nil +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go new file mode 100644 index 0000000000..301b2315bb --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go @@ -0,0 +1,304 @@ +//go:build windows +// +build windows + +package common + +import ( + "context" + "fmt" + "path/filepath" + "reflect" + "strings" + "syscall" + "unsafe" + + "github.com/yusufpapurcu/wmi" + "golang.org/x/sys/windows" +) + +// for double values +type PDH_FMT_COUNTERVALUE_DOUBLE struct { + CStatus uint32 + DoubleValue float64 +} + +// for 64 bit integer values +type PDH_FMT_COUNTERVALUE_LARGE struct { + CStatus uint32 + LargeValue int64 +} + +// for long values +type PDH_FMT_COUNTERVALUE_LONG struct { + CStatus uint32 + LongValue int32 + padding [4]byte +} + +// windows system const +const ( + ERROR_SUCCESS = 0 + ERROR_FILE_NOT_FOUND = 2 + DRIVE_REMOVABLE = 2 + DRIVE_FIXED = 3 + HKEY_LOCAL_MACHINE = 0x80000002 + RRF_RT_REG_SZ = 0x00000002 + RRF_RT_REG_DWORD = 0x00000010 + PDH_FMT_LONG = 0x00000100 + PDH_FMT_DOUBLE = 0x00000200 + PDH_FMT_LARGE = 0x00000400 + PDH_INVALID_DATA = 0xc0000bc6 + PDH_INVALID_HANDLE = 0xC0000bbc + PDH_NO_DATA = 0x800007d5 + + STATUS_BUFFER_OVERFLOW = 0x80000005 + STATUS_BUFFER_TOO_SMALL = 0xC0000023 + STATUS_INFO_LENGTH_MISMATCH = 0xC0000004 +) + +const ( + ProcessBasicInformation = 0 + ProcessWow64Information = 26 + ProcessQueryInformation = windows.PROCESS_DUP_HANDLE | windows.PROCESS_QUERY_INFORMATION + + SystemExtendedHandleInformationClass = 64 +) + +var ( + Modkernel32 = windows.NewLazySystemDLL("kernel32.dll") + ModNt = windows.NewLazySystemDLL("ntdll.dll") + ModPdh = windows.NewLazySystemDLL("pdh.dll") + ModPsapi = windows.NewLazySystemDLL("psapi.dll") + + ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes") + ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation") + ProcRtlGetNativeSystemInformation = ModNt.NewProc("RtlGetNativeSystemInformation") + ProcRtlNtStatusToDosError = ModNt.NewProc("RtlNtStatusToDosError") + ProcNtQueryInformationProcess = ModNt.NewProc("NtQueryInformationProcess") + ProcNtReadVirtualMemory = ModNt.NewProc("NtReadVirtualMemory") + ProcNtWow64QueryInformationProcess64 = ModNt.NewProc("NtWow64QueryInformationProcess64") + ProcNtWow64ReadVirtualMemory64 = ModNt.NewProc("NtWow64ReadVirtualMemory64") + + PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery") + PdhAddEnglishCounterW = ModPdh.NewProc("PdhAddEnglishCounterW") + PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData") + PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue") + PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery") + + procQueryDosDeviceW = Modkernel32.NewProc("QueryDosDeviceW") +) + +type FILETIME struct { + DwLowDateTime uint32 + DwHighDateTime uint32 +} + +// borrowed from net/interface_windows.go +func BytePtrToString(p *uint8) string { + a := (*[10000]uint8)(unsafe.Pointer(p)) + i := 0 + for a[i] != 0 { + i++ + } + return string(a[:i]) +} + +// CounterInfo struct is used to track a windows performance counter +// copied from https://github.com/mackerelio/mackerel-agent/ +type CounterInfo struct { + PostName string + CounterName string + Counter windows.Handle +} + +// CreateQuery with a PdhOpenQuery call +// copied from https://github.com/mackerelio/mackerel-agent/ +func CreateQuery() (windows.Handle, error) { + var query windows.Handle + r, _, err := PdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&query))) + if r != 0 { + return 0, err + } + return query, nil +} + +// CreateCounter with a PdhAddEnglishCounterW call +func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, error) { + var counter windows.Handle + r, _, err := PdhAddEnglishCounterW.Call( + uintptr(query), + uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(cname))), + 0, + uintptr(unsafe.Pointer(&counter))) + if r != 0 { + return nil, err + } + return &CounterInfo{ + PostName: pname, + CounterName: cname, + Counter: counter, + }, nil +} + +// GetCounterValue get counter value from handle +// adapted from https://github.com/mackerelio/mackerel-agent/ +func GetCounterValue(counter windows.Handle) (float64, error) { + var value PDH_FMT_COUNTERVALUE_DOUBLE + r, _, err := PdhGetFormattedCounterValue.Call(uintptr(counter), PDH_FMT_DOUBLE, uintptr(0), uintptr(unsafe.Pointer(&value))) + if r != 0 && r != PDH_INVALID_DATA { + return 0.0, err + } + return value.DoubleValue, nil +} + +type Win32PerformanceCounter struct { + PostName string + CounterName string + Query windows.Handle + Counter windows.Handle +} + +func NewWin32PerformanceCounter(postName, counterName string) (*Win32PerformanceCounter, error) { + query, err := CreateQuery() + if err != nil { + return nil, err + } + counter := Win32PerformanceCounter{ + Query: query, + PostName: postName, + CounterName: counterName, + } + r, _, err := PdhAddEnglishCounterW.Call( + uintptr(counter.Query), + uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(counter.CounterName))), + 0, + uintptr(unsafe.Pointer(&counter.Counter)), + ) + if r != 0 { + return nil, err + } + return &counter, nil +} + +func (w *Win32PerformanceCounter) GetValue() (float64, error) { + r, _, err := PdhCollectQueryData.Call(uintptr(w.Query)) + if r != 0 && err != nil { + if r == PDH_NO_DATA { + return 0.0, fmt.Errorf("%w: this counter has not data", err) + } + return 0.0, err + } + + return GetCounterValue(w.Counter) +} + +func ProcessorQueueLengthCounter() (*Win32PerformanceCounter, error) { + return NewWin32PerformanceCounter("processor_queue_length", `\System\Processor Queue Length`) +} + +// WMIQueryWithContext - wraps wmi.Query with a timed-out context to avoid hanging +func WMIQueryWithContext(ctx context.Context, query string, dst interface{}, connectServerArgs ...interface{}) error { + if _, ok := ctx.Deadline(); !ok { + ctxTimeout, cancel := context.WithTimeout(ctx, Timeout) + defer cancel() + ctx = ctxTimeout + } + + errChan := make(chan error, 1) + go func() { + errChan <- wmi.Query(query, dst, connectServerArgs...) + }() + + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-errChan: + return err + } +} + +// Convert paths using native DOS format like: +// +// "\Device\HarddiskVolume1\Windows\systemew\file.txt" +// +// into: +// +// "C:\Windows\systemew\file.txt" +func ConvertDOSPath(p string) string { + rawDrive := strings.Join(strings.Split(p, `\`)[:3], `\`) + + for d := 'A'; d <= 'Z'; d++ { + szDeviceName := string(d) + ":" + szTarget := make([]uint16, 512) + ret, _, _ := procQueryDosDeviceW.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(szDeviceName))), + uintptr(unsafe.Pointer(&szTarget[0])), + uintptr(len(szTarget))) + if ret != 0 && windows.UTF16ToString(szTarget[:]) == rawDrive { + return filepath.Join(szDeviceName, p[len(rawDrive):]) + } + } + return p +} + +type NtStatus uint32 + +func (s NtStatus) Error() error { + if s == 0 { + return nil + } + return fmt.Errorf("NtStatus 0x%08x", uint32(s)) +} + +func (s NtStatus) IsError() bool { + return s>>30 == 3 +} + +type SystemExtendedHandleTableEntryInformation struct { + Object uintptr + UniqueProcessId uintptr + HandleValue uintptr + GrantedAccess uint32 + CreatorBackTraceIndex uint16 + ObjectTypeIndex uint16 + HandleAttributes uint32 + Reserved uint32 +} + +type SystemExtendedHandleInformation struct { + NumberOfHandles uintptr + Reserved uintptr + Handles [1]SystemExtendedHandleTableEntryInformation +} + +// CallWithExpandingBuffer https://github.com/hillu/go-ntdll +func CallWithExpandingBuffer(fn func() NtStatus, buf *[]byte, resultLength *uint32) NtStatus { + for { + if st := fn(); st == STATUS_BUFFER_OVERFLOW || st == STATUS_BUFFER_TOO_SMALL || st == STATUS_INFO_LENGTH_MISMATCH { + if int(*resultLength) <= cap(*buf) { + (*reflect.SliceHeader)(unsafe.Pointer(buf)).Len = int(*resultLength) + } else { + *buf = make([]byte, int(*resultLength)) + } + continue + } else { + if !st.IsError() { + *buf = (*buf)[:int(*resultLength)] + } + return st + } + } +} + +func NtQuerySystemInformation( + SystemInformationClass uint32, + SystemInformation *byte, + SystemInformationLength uint32, + ReturnLength *uint32, +) NtStatus { + r0, _, _ := ProcNtQuerySystemInformation.Call( + uintptr(SystemInformationClass), + uintptr(unsafe.Pointer(SystemInformation)), + uintptr(SystemInformationLength), + uintptr(unsafe.Pointer(ReturnLength))) + return NtStatus(r0) +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/endian.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/endian.go new file mode 100644 index 0000000000..147cfdc4b7 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/endian.go @@ -0,0 +1,10 @@ +package common + +import "unsafe" + +// IsLittleEndian checks if the current platform uses little-endian. +// copied from https://github.com/ntrrg/ntgo/blob/v0.8.0/runtime/infrastructure.go#L16 (MIT License) +func IsLittleEndian() bool { + var x int16 = 0x0011 + return *(*byte)(unsafe.Pointer(&x)) == 0x11 +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go new file mode 100644 index 0000000000..9bed2419ed --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go @@ -0,0 +1,21 @@ +package common + +import ( + "context" + "time" +) + +// Sleep awaits for provided interval. +// Can be interrupted by context cancelation. +func Sleep(ctx context.Context, interval time.Duration) error { + timer := time.NewTimer(interval) + select { + case <-ctx.Done(): + if !timer.Stop() { + <-timer.C + } + return ctx.Err() + case <-timer.C: + return nil + } +} diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go new file mode 100644 index 0000000000..a4aaadaf54 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go @@ -0,0 +1,30 @@ +package common + +import "fmt" + +type Warnings struct { + List []error + Verbose bool +} + +func (w *Warnings) Add(err error) { + w.List = append(w.List, err) +} + +func (w *Warnings) Reference() error { + if len(w.List) > 0 { + return w + } + return nil +} + +func (w *Warnings) Error() string { + if w.Verbose { + str := "" + for i, e := range w.List { + str += fmt.Sprintf("\tError %d: %s\n", i, e.Error()) + } + return str + } + return fmt.Sprintf("Number of warnings: %v", len(w.List)) +} diff --git a/vendor/github.com/yusufpapurcu/wmi/LICENSE b/vendor/github.com/yusufpapurcu/wmi/LICENSE new file mode 100644 index 0000000000..ae80b67209 --- /dev/null +++ b/vendor/github.com/yusufpapurcu/wmi/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Stack Exchange + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/yusufpapurcu/wmi/README.md b/vendor/github.com/yusufpapurcu/wmi/README.md new file mode 100644 index 0000000000..426d1a46b4 --- /dev/null +++ b/vendor/github.com/yusufpapurcu/wmi/README.md @@ -0,0 +1,6 @@ +wmi +=== + +Package wmi provides a WQL interface to Windows WMI. + +Note: It interfaces with WMI on the local machine, therefore it only runs on Windows. diff --git a/vendor/github.com/yusufpapurcu/wmi/swbemservices.go b/vendor/github.com/yusufpapurcu/wmi/swbemservices.go new file mode 100644 index 0000000000..a250c846d5 --- /dev/null +++ b/vendor/github.com/yusufpapurcu/wmi/swbemservices.go @@ -0,0 +1,261 @@ +//go:build windows +// +build windows + +package wmi + +import ( + "fmt" + "reflect" + "runtime" + "sync" + + "github.com/go-ole/go-ole" + "github.com/go-ole/go-ole/oleutil" +) + +// SWbemServices is used to access wmi. See https://msdn.microsoft.com/en-us/library/aa393719(v=vs.85).aspx +type SWbemServices struct { + //TODO: track namespace. Not sure if we can re connect to a different namespace using the same instance + cWMIClient *Client //This could also be an embedded struct, but then we would need to branch on Client vs SWbemServices in the Query method + sWbemLocatorIUnknown *ole.IUnknown + sWbemLocatorIDispatch *ole.IDispatch + queries chan *queryRequest + closeError chan error + lQueryorClose sync.Mutex +} + +type queryRequest struct { + query string + dst interface{} + args []interface{} + finished chan error +} + +// InitializeSWbemServices will return a new SWbemServices object that can be used to query WMI +func InitializeSWbemServices(c *Client, connectServerArgs ...interface{}) (*SWbemServices, error) { + //fmt.Println("InitializeSWbemServices: Starting") + //TODO: implement connectServerArgs as optional argument for init with connectServer call + s := new(SWbemServices) + s.cWMIClient = c + s.queries = make(chan *queryRequest) + initError := make(chan error) + go s.process(initError) + + err, ok := <-initError + if ok { + return nil, err //Send error to caller + } + //fmt.Println("InitializeSWbemServices: Finished") + return s, nil +} + +// Close will clear and release all of the SWbemServices resources +func (s *SWbemServices) Close() error { + s.lQueryorClose.Lock() + if s == nil || s.sWbemLocatorIDispatch == nil { + s.lQueryorClose.Unlock() + return fmt.Errorf("SWbemServices is not Initialized") + } + if s.queries == nil { + s.lQueryorClose.Unlock() + return fmt.Errorf("SWbemServices has been closed") + } + //fmt.Println("Close: sending close request") + var result error + ce := make(chan error) + s.closeError = ce //Race condition if multiple callers to close. May need to lock here + close(s.queries) //Tell background to shut things down + s.lQueryorClose.Unlock() + err, ok := <-ce + if ok { + result = err + } + //fmt.Println("Close: finished") + return result +} + +func (s *SWbemServices) process(initError chan error) { + //fmt.Println("process: starting background thread initialization") + //All OLE/WMI calls must happen on the same initialized thead, so lock this goroutine + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED) + if err != nil { + oleCode := err.(*ole.OleError).Code() + if oleCode != ole.S_OK && oleCode != S_FALSE { + initError <- fmt.Errorf("ole.CoInitializeEx error: %v", err) + return + } + } + defer ole.CoUninitialize() + + unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator") + if err != nil { + initError <- fmt.Errorf("CreateObject SWbemLocator error: %v", err) + return + } else if unknown == nil { + initError <- ErrNilCreateObject + return + } + defer unknown.Release() + s.sWbemLocatorIUnknown = unknown + + dispatch, err := s.sWbemLocatorIUnknown.QueryInterface(ole.IID_IDispatch) + if err != nil { + initError <- fmt.Errorf("SWbemLocator QueryInterface error: %v", err) + return + } + defer dispatch.Release() + s.sWbemLocatorIDispatch = dispatch + + // we can't do the ConnectServer call outside the loop unless we find a way to track and re-init the connectServerArgs + //fmt.Println("process: initialized. closing initError") + close(initError) + //fmt.Println("process: waiting for queries") + for q := range s.queries { + //fmt.Printf("process: new query: len(query)=%d\n", len(q.query)) + errQuery := s.queryBackground(q) + //fmt.Println("process: s.queryBackground finished") + if errQuery != nil { + q.finished <- errQuery + } + close(q.finished) + } + //fmt.Println("process: queries channel closed") + s.queries = nil //set channel to nil so we know it is closed + //TODO: I think the Release/Clear calls can panic if things are in a bad state. + //TODO: May need to recover from panics and send error to method caller instead. + close(s.closeError) +} + +// Query runs the WQL query using a SWbemServices instance and appends the values to dst. +// +// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in +// the query must have the same name in dst. Supported types are all signed and +// unsigned integers, time.Time, string, bool, or a pointer to one of those. +// Array types are not supported. +// +// By default, the local machine and default namespace are used. These can be +// changed using connectServerArgs. See +// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details. +func (s *SWbemServices) Query(query string, dst interface{}, connectServerArgs ...interface{}) error { + s.lQueryorClose.Lock() + if s == nil || s.sWbemLocatorIDispatch == nil { + s.lQueryorClose.Unlock() + return fmt.Errorf("SWbemServices is not Initialized") + } + if s.queries == nil { + s.lQueryorClose.Unlock() + return fmt.Errorf("SWbemServices has been closed") + } + + //fmt.Println("Query: Sending query request") + qr := queryRequest{ + query: query, + dst: dst, + args: connectServerArgs, + finished: make(chan error), + } + s.queries <- &qr + s.lQueryorClose.Unlock() + err, ok := <-qr.finished + if ok { + //fmt.Println("Query: Finished with error") + return err //Send error to caller + } + //fmt.Println("Query: Finished") + return nil +} + +func (s *SWbemServices) queryBackground(q *queryRequest) error { + if s == nil || s.sWbemLocatorIDispatch == nil { + return fmt.Errorf("SWbemServices is not Initialized") + } + wmi := s.sWbemLocatorIDispatch //Should just rename in the code, but this will help as we break things apart + //fmt.Println("queryBackground: Starting") + + dv := reflect.ValueOf(q.dst) + if dv.Kind() != reflect.Ptr || dv.IsNil() { + return ErrInvalidEntityType + } + dv = dv.Elem() + mat, elemType := checkMultiArg(dv) + if mat == multiArgTypeInvalid { + return ErrInvalidEntityType + } + + // service is a SWbemServices + serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", q.args...) + if err != nil { + return err + } + service := serviceRaw.ToIDispatch() + defer serviceRaw.Clear() + + // result is a SWBemObjectSet + resultRaw, err := oleutil.CallMethod(service, "ExecQuery", q.query) + if err != nil { + return err + } + result := resultRaw.ToIDispatch() + defer resultRaw.Clear() + + count, err := oleInt64(result, "Count") + if err != nil { + return err + } + + enumProperty, err := result.GetProperty("_NewEnum") + if err != nil { + return err + } + defer enumProperty.Clear() + + enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant) + if err != nil { + return err + } + if enum == nil { + return fmt.Errorf("can't get IEnumVARIANT, enum is nil") + } + defer enum.Release() + + // Initialize a slice with Count capacity + dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count))) + + var errFieldMismatch error + for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) { + if err != nil { + return err + } + + err := func() error { + // item is a SWbemObject, but really a Win32_Process + item := itemRaw.ToIDispatch() + defer item.Release() + + ev := reflect.New(elemType) + if err = s.cWMIClient.loadEntity(ev.Interface(), item); err != nil { + if _, ok := err.(*ErrFieldMismatch); ok { + // We continue loading entities even in the face of field mismatch errors. + // If we encounter any other error, that other error is returned. Otherwise, + // an ErrFieldMismatch is returned. + errFieldMismatch = err + } else { + return err + } + } + if mat != multiArgTypeStructPtr { + ev = ev.Elem() + } + dv.Set(reflect.Append(dv, ev)) + return nil + }() + if err != nil { + return err + } + } + //fmt.Println("queryBackground: Finished") + return errFieldMismatch +} diff --git a/vendor/github.com/yusufpapurcu/wmi/wmi.go b/vendor/github.com/yusufpapurcu/wmi/wmi.go new file mode 100644 index 0000000000..03f386ed59 --- /dev/null +++ b/vendor/github.com/yusufpapurcu/wmi/wmi.go @@ -0,0 +1,603 @@ +//go:build windows +// +build windows + +/* +Package wmi provides a WQL interface for WMI on Windows. + +Example code to print names of running processes: + + type Win32_Process struct { + Name string + } + + func main() { + var dst []Win32_Process + q := wmi.CreateQuery(&dst, "") + err := wmi.Query(q, &dst) + if err != nil { + log.Fatal(err) + } + for i, v := range dst { + println(i, v.Name) + } + } +*/ +package wmi + +import ( + "bytes" + "errors" + "fmt" + "log" + "os" + "reflect" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "github.com/go-ole/go-ole" + "github.com/go-ole/go-ole/oleutil" +) + +var l = log.New(os.Stdout, "", log.LstdFlags) + +var ( + ErrInvalidEntityType = errors.New("wmi: invalid entity type") + // ErrNilCreateObject is the error returned if CreateObject returns nil even + // if the error was nil. + ErrNilCreateObject = errors.New("wmi: create object returned nil") + lock sync.Mutex +) + +// S_FALSE is returned by CoInitializeEx if it was already called on this thread. +const S_FALSE = 0x00000001 + +// QueryNamespace invokes Query with the given namespace on the local machine. +func QueryNamespace(query string, dst interface{}, namespace string) error { + return Query(query, dst, nil, namespace) +} + +// Query runs the WQL query and appends the values to dst. +// +// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in +// the query must have the same name in dst. Supported types are all signed and +// unsigned integers, time.Time, string, bool, or a pointer to one of those. +// Array types are not supported. +// +// By default, the local machine and default namespace are used. These can be +// changed using connectServerArgs. See +// https://docs.microsoft.com/en-us/windows/desktop/WmiSdk/swbemlocator-connectserver +// for details. +// +// Query is a wrapper around DefaultClient.Query. +func Query(query string, dst interface{}, connectServerArgs ...interface{}) error { + if DefaultClient.SWbemServicesClient == nil { + return DefaultClient.Query(query, dst, connectServerArgs...) + } + return DefaultClient.SWbemServicesClient.Query(query, dst, connectServerArgs...) +} + +// CallMethod calls a method named methodName on an instance of the class named +// className, with the given params. +// +// CallMethod is a wrapper around DefaultClient.CallMethod. +func CallMethod(connectServerArgs []interface{}, className, methodName string, params []interface{}) (int32, error) { + return DefaultClient.CallMethod(connectServerArgs, className, methodName, params) +} + +// A Client is an WMI query client. +// +// Its zero value (DefaultClient) is a usable client. +type Client struct { + // NonePtrZero specifies if nil values for fields which aren't pointers + // should be returned as the field types zero value. + // + // Setting this to true allows stucts without pointer fields to be used + // without the risk failure should a nil value returned from WMI. + NonePtrZero bool + + // PtrNil specifies if nil values for pointer fields should be returned + // as nil. + // + // Setting this to true will set pointer fields to nil where WMI + // returned nil, otherwise the types zero value will be returned. + PtrNil bool + + // AllowMissingFields specifies that struct fields not present in the + // query result should not result in an error. + // + // Setting this to true allows custom queries to be used with full + // struct definitions instead of having to define multiple structs. + AllowMissingFields bool + + // SWbemServiceClient is an optional SWbemServices object that can be + // initialized and then reused across multiple queries. If it is null + // then the method will initialize a new temporary client each time. + SWbemServicesClient *SWbemServices +} + +// DefaultClient is the default Client and is used by Query, QueryNamespace, and CallMethod. +var DefaultClient = &Client{} + +// coinitService coinitializes WMI service. If no error is returned, a cleanup function +// is returned which must be executed (usually deferred) to clean up allocated resources. +func (c *Client) coinitService(connectServerArgs ...interface{}) (*ole.IDispatch, func(), error) { + var unknown *ole.IUnknown + var wmi *ole.IDispatch + var serviceRaw *ole.VARIANT + + // be sure teardown happens in the reverse + // order from that which they were created + deferFn := func() { + if serviceRaw != nil { + serviceRaw.Clear() + } + if wmi != nil { + wmi.Release() + } + if unknown != nil { + unknown.Release() + } + ole.CoUninitialize() + } + + // if we error'ed here, clean up immediately + var err error + defer func() { + if err != nil { + deferFn() + } + }() + + err = ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED) + if err != nil { + oleCode := err.(*ole.OleError).Code() + if oleCode != ole.S_OK && oleCode != S_FALSE { + return nil, nil, err + } + } + + unknown, err = oleutil.CreateObject("WbemScripting.SWbemLocator") + if err != nil { + return nil, nil, err + } else if unknown == nil { + return nil, nil, ErrNilCreateObject + } + + wmi, err = unknown.QueryInterface(ole.IID_IDispatch) + if err != nil { + return nil, nil, err + } + + // service is a SWbemServices + serviceRaw, err = oleutil.CallMethod(wmi, "ConnectServer", connectServerArgs...) + if err != nil { + return nil, nil, err + } + + return serviceRaw.ToIDispatch(), deferFn, nil +} + +// CallMethod calls a WMI method named methodName on an instance +// of the class named className. It passes in the arguments given +// in params. Use connectServerArgs to customize the machine and +// namespace; by default, the local machine and default namespace +// are used. See +// https://docs.microsoft.com/en-us/windows/desktop/WmiSdk/swbemlocator-connectserver +// for details. +func (c *Client) CallMethod(connectServerArgs []interface{}, className, methodName string, params []interface{}) (int32, error) { + service, cleanup, err := c.coinitService(connectServerArgs...) + if err != nil { + return 0, fmt.Errorf("coinit: %v", err) + } + defer cleanup() + + // Get class + classRaw, err := oleutil.CallMethod(service, "Get", className) + if err != nil { + return 0, fmt.Errorf("CallMethod Get class %s: %v", className, err) + } + class := classRaw.ToIDispatch() + defer classRaw.Clear() + + // Run method + resultRaw, err := oleutil.CallMethod(class, methodName, params...) + if err != nil { + return 0, fmt.Errorf("CallMethod %s.%s: %v", className, methodName, err) + } + resultInt, ok := resultRaw.Value().(int32) + if !ok { + return 0, fmt.Errorf("return value was not an int32: %v (%T)", resultRaw, resultRaw) + } + + return resultInt, nil +} + +// Query runs the WQL query and appends the values to dst. +// +// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in +// the query must have the same name in dst. Supported types are all signed and +// unsigned integers, time.Time, string, bool, or a pointer to one of those. +// Array types are not supported. +// +// By default, the local machine and default namespace are used. These can be +// changed using connectServerArgs. See +// https://docs.microsoft.com/en-us/windows/desktop/WmiSdk/swbemlocator-connectserver +// for details. +func (c *Client) Query(query string, dst interface{}, connectServerArgs ...interface{}) error { + dv := reflect.ValueOf(dst) + if dv.Kind() != reflect.Ptr || dv.IsNil() { + return ErrInvalidEntityType + } + dv = dv.Elem() + mat, elemType := checkMultiArg(dv) + if mat == multiArgTypeInvalid { + return ErrInvalidEntityType + } + + lock.Lock() + defer lock.Unlock() + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + service, cleanup, err := c.coinitService(connectServerArgs...) + if err != nil { + return err + } + defer cleanup() + + // result is a SWBemObjectSet + resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query) + if err != nil { + return err + } + result := resultRaw.ToIDispatch() + defer resultRaw.Clear() + + count, err := oleInt64(result, "Count") + if err != nil { + return err + } + + enumProperty, err := result.GetProperty("_NewEnum") + if err != nil { + return err + } + defer enumProperty.Clear() + + enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant) + if err != nil { + return err + } + if enum == nil { + return fmt.Errorf("can't get IEnumVARIANT, enum is nil") + } + defer enum.Release() + + // Initialize a slice with Count capacity + dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count))) + + var errFieldMismatch error + for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) { + if err != nil { + return err + } + + err := func() error { + // item is a SWbemObject, but really a Win32_Process + item := itemRaw.ToIDispatch() + defer item.Release() + + ev := reflect.New(elemType) + if err = c.loadEntity(ev.Interface(), item); err != nil { + if _, ok := err.(*ErrFieldMismatch); ok { + // We continue loading entities even in the face of field mismatch errors. + // If we encounter any other error, that other error is returned. Otherwise, + // an ErrFieldMismatch is returned. + errFieldMismatch = err + } else { + return err + } + } + if mat != multiArgTypeStructPtr { + ev = ev.Elem() + } + dv.Set(reflect.Append(dv, ev)) + return nil + }() + if err != nil { + return err + } + } + return errFieldMismatch +} + +// ErrFieldMismatch is returned when a field is to be loaded into a different +// type than the one it was stored from, or when a field is missing or +// unexported in the destination struct. +// StructType is the type of the struct pointed to by the destination argument. +type ErrFieldMismatch struct { + StructType reflect.Type + FieldName string + Reason string +} + +func (e *ErrFieldMismatch) Error() string { + return fmt.Sprintf("wmi: cannot load field %q into a %q: %s", + e.FieldName, e.StructType, e.Reason) +} + +var timeType = reflect.TypeOf(time.Time{}) + +// loadEntity loads a SWbemObject into a struct pointer. +func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismatch error) { + v := reflect.ValueOf(dst).Elem() + for i := 0; i < v.NumField(); i++ { + f := v.Field(i) + of := f + isPtr := f.Kind() == reflect.Ptr + n := v.Type().Field(i).Name + if n[0] < 'A' || n[0] > 'Z' { + continue + } + if !f.CanSet() { + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "CanSet() is false", + } + } + prop, err := oleutil.GetProperty(src, n) + if err != nil { + if !c.AllowMissingFields { + errFieldMismatch = &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "no such struct field", + } + } + continue + } + defer prop.Clear() + + if isPtr && !(c.PtrNil && prop.VT == 0x1) { + ptr := reflect.New(f.Type().Elem()) + f.Set(ptr) + f = f.Elem() + } + + if prop.VT == 0x1 { //VT_NULL + continue + } + + switch val := prop.Value().(type) { + case int8, int16, int32, int64, int: + v := reflect.ValueOf(val).Int() + switch f.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + f.SetInt(v) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + f.SetUint(uint64(v)) + default: + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "not an integer class", + } + } + case uint8, uint16, uint32, uint64: + v := reflect.ValueOf(val).Uint() + switch f.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + f.SetInt(int64(v)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + f.SetUint(v) + default: + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "not an integer class", + } + } + case string: + switch f.Kind() { + case reflect.String: + f.SetString(val) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + iv, err := strconv.ParseInt(val, 10, 64) + if err != nil { + return err + } + f.SetInt(iv) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + uv, err := strconv.ParseUint(val, 10, 64) + if err != nil { + return err + } + f.SetUint(uv) + case reflect.Struct: + switch f.Type() { + case timeType: + if len(val) == 25 { + mins, err := strconv.Atoi(val[22:]) + if err != nil { + return err + } + val = val[:22] + fmt.Sprintf("%02d%02d", mins/60, mins%60) + } + t, err := time.Parse("20060102150405.000000-0700", val) + if err != nil { + return err + } + f.Set(reflect.ValueOf(t)) + } + } + case bool: + switch f.Kind() { + case reflect.Bool: + f.SetBool(val) + default: + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "not a bool", + } + } + case float32: + switch f.Kind() { + case reflect.Float32: + f.SetFloat(float64(val)) + default: + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "not a Float32", + } + } + case float64: + switch f.Kind() { + case reflect.Float32, reflect.Float64: + f.SetFloat(val) + default: + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: "not a Float64", + } + } + + default: + if f.Kind() == reflect.Slice { + switch f.Type().Elem().Kind() { + case reflect.String: + safeArray := prop.ToArray() + if safeArray != nil { + arr := safeArray.ToValueArray() + fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr)) + for i, v := range arr { + s := fArr.Index(i) + s.SetString(v.(string)) + } + f.Set(fArr) + } + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + safeArray := prop.ToArray() + if safeArray != nil { + arr := safeArray.ToValueArray() + fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr)) + for i, v := range arr { + s := fArr.Index(i) + s.SetUint(reflect.ValueOf(v).Uint()) + } + f.Set(fArr) + } + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + safeArray := prop.ToArray() + if safeArray != nil { + arr := safeArray.ToValueArray() + fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr)) + for i, v := range arr { + s := fArr.Index(i) + s.SetInt(reflect.ValueOf(v).Int()) + } + f.Set(fArr) + } + default: + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: fmt.Sprintf("unsupported slice type (%T)", val), + } + } + } else { + typeof := reflect.TypeOf(val) + if typeof == nil && (isPtr || c.NonePtrZero) { + if (isPtr && c.PtrNil) || (!isPtr && c.NonePtrZero) { + of.Set(reflect.Zero(of.Type())) + } + break + } + return &ErrFieldMismatch{ + StructType: of.Type(), + FieldName: n, + Reason: fmt.Sprintf("unsupported type (%T)", val), + } + } + } + } + return errFieldMismatch +} + +type multiArgType int + +const ( + multiArgTypeInvalid multiArgType = iota + multiArgTypeStruct + multiArgTypeStructPtr +) + +// checkMultiArg checks that v has type []S, []*S for some struct type S. +// +// It returns what category the slice's elements are, and the reflect.Type +// that represents S. +func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) { + if v.Kind() != reflect.Slice { + return multiArgTypeInvalid, nil + } + elemType = v.Type().Elem() + switch elemType.Kind() { + case reflect.Struct: + return multiArgTypeStruct, elemType + case reflect.Ptr: + elemType = elemType.Elem() + if elemType.Kind() == reflect.Struct { + return multiArgTypeStructPtr, elemType + } + } + return multiArgTypeInvalid, nil +} + +func oleInt64(item *ole.IDispatch, prop string) (int64, error) { + v, err := oleutil.GetProperty(item, prop) + if err != nil { + return 0, err + } + defer v.Clear() + + i := int64(v.Val) + return i, nil +} + +// CreateQuery returns a WQL query string that queries all columns of src. where +// is an optional string that is appended to the query, to be used with WHERE +// clauses. In such a case, the "WHERE" string should appear at the beginning. +// The wmi class is obtained by the name of the type. You can pass a optional +// class throught the variadic class parameter which is useful for anonymous +// structs. +func CreateQuery(src interface{}, where string, class ...string) string { + var b bytes.Buffer + b.WriteString("SELECT ") + s := reflect.Indirect(reflect.ValueOf(src)) + t := s.Type() + if s.Kind() == reflect.Slice { + t = t.Elem() + } + if t.Kind() != reflect.Struct { + return "" + } + var fields []string + for i := 0; i < t.NumField(); i++ { + fields = append(fields, t.Field(i).Name) + } + b.WriteString(strings.Join(fields, ", ")) + b.WriteString(" FROM ") + if len(class) > 0 { + b.WriteString(class[0]) + } else { + b.WriteString(t.Name()) + } + b.WriteString(" " + where) + return b.String() +} diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index b18efb743f..948a3ee63d 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -4,6 +4,9 @@ // Package errgroup provides synchronization, error propagation, and Context // cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. package errgroup import ( diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go index e7d3df4bd3..b0e4198575 100644 --- a/vendor/golang.org/x/sys/unix/aliases.go +++ b/vendor/golang.org/x/sys/unix/aliases.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos package unix diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index c6492020ec..fdcaa974d2 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -584,7 +584,7 @@ ccflags="$@" $2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || $2 ~ /^KEYCTL_/ || $2 ~ /^PERF_/ || - $2 ~ /^SECCOMP_MODE_/ || + $2 ~ /^SECCOMP_/ || $2 ~ /^SEEK_/ || $2 ~ /^SCHED_/ || $2 ~ /^SPLICE_/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go index 16dc699379..2f0fa76e4f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build darwin && go1.12 +//go:build darwin package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 64d1bb4dba..2b57e0f73b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -13,6 +13,7 @@ package unix import ( + "errors" "sync" "unsafe" ) @@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Uname(uname *Utsname) error { mib := []_C_int{CTL_KERN, KERN_OSTYPE} n := unsafe.Sizeof(uname.Sysname) - if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + // Suppress ENOMEM errors to be compatible with the C library __xuname() implementation. + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_HOSTNAME} n = unsafe.Sizeof(uname.Nodename) - if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_OSRELEASE} n = unsafe.Sizeof(uname.Release) - if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_VERSION} n = unsafe.Sizeof(uname.Version) - if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } @@ -205,7 +207,7 @@ func Uname(uname *Utsname) error { mib = []_C_int{CTL_HW, HW_MACHINE} n = unsafe.Sizeof(uname.Machine) - if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 0f85e29e62..5682e2628a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error { //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) //sys Fsopen(fsName string, flags int) (fd int, err error) //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) + +//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) + +func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) { + var keyp *byte + if keyp, err = BytePtrFromString(key); err != nil { + return + } + return fsconfig(fd, cmd, keyp, value, aux) +} + +// FsconfigSetFlag is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FLAG. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +func FsconfigSetFlag(fd int, key string) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0) +} + +// FsconfigSetString is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_STRING. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetString(fd int, key string, value string) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(value); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0) +} + +// FsconfigSetBinary is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_BINARY. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetBinary(fd int, key string, value []byte) (err error) { + if len(value) == 0 { + return EINVAL + } + return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value)) +} + +// FsconfigSetPath is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// path is a non-empty path for specified key. +// atfd is a file descriptor at which to start lookup from or AT_FDCWD. +func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd) +} + +// FsconfigSetPathEmpty is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as +// FconfigSetPath but with AT_PATH_EMPTY implied. +func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd) +} + +// FsconfigSetFd is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FD. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is a file descriptor to be assigned to specified key. +func FsconfigSetFd(fd int, key string, value int) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value) +} + +// FsconfigCreate is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_CREATE. +// +// fd is the filesystem context to act upon. +func FsconfigCreate(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0) +} + +// FsconfigReconfigure is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_RECONFIGURE. +// +// fd is the filesystem context to act upon. +func FsconfigReconfigure(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) +} + //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sysnb Getpgid(pid int) (pgid int, err error) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index a5d3ff8df9..36bf8399f4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -1785,6 +1785,8 @@ const ( LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20 LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000 LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 + LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 + LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef @@ -2465,6 +2467,7 @@ const ( PR_MCE_KILL_GET = 0x22 PR_MCE_KILL_LATE = 0x0 PR_MCE_KILL_SET = 0x1 + PR_MDWE_NO_INHERIT = 0x2 PR_MDWE_REFUSE_EXEC_GAIN = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b @@ -2669,8 +2672,9 @@ const ( RTAX_FEATURES = 0xc RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ECN = 0x1 - RTAX_FEATURE_MASK = 0xf + RTAX_FEATURE_MASK = 0x1f RTAX_FEATURE_SACK = 0x2 + RTAX_FEATURE_TCP_USEC_TS = 0x10 RTAX_FEATURE_TIMESTAMP = 0x4 RTAX_HOPLIMIT = 0xa RTAX_INITCWND = 0xb @@ -2913,9 +2917,38 @@ const ( SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x1d SC_LOG_FLUSH = 0x100000 + SECCOMP_ADDFD_FLAG_SEND = 0x2 + SECCOMP_ADDFD_FLAG_SETFD = 0x1 + SECCOMP_FILTER_FLAG_LOG = 0x2 + SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8 + SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4 + SECCOMP_FILTER_FLAG_TSYNC = 0x1 + SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10 + SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20 + SECCOMP_GET_ACTION_AVAIL = 0x2 + SECCOMP_GET_NOTIF_SIZES = 0x3 + SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100 + SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101 + SECCOMP_IOC_MAGIC = '!' SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_STRICT = 0x1 + SECCOMP_RET_ACTION = 0x7fff0000 + SECCOMP_RET_ACTION_FULL = 0xffff0000 + SECCOMP_RET_ALLOW = 0x7fff0000 + SECCOMP_RET_DATA = 0xffff + SECCOMP_RET_ERRNO = 0x50000 + SECCOMP_RET_KILL = 0x0 + SECCOMP_RET_KILL_PROCESS = 0x80000000 + SECCOMP_RET_KILL_THREAD = 0x0 + SECCOMP_RET_LOG = 0x7ffc0000 + SECCOMP_RET_TRACE = 0x7ff00000 + SECCOMP_RET_TRAP = 0x30000 + SECCOMP_RET_USER_NOTIF = 0x7fc00000 + SECCOMP_SET_MODE_FILTER = 0x1 + SECCOMP_SET_MODE_STRICT = 0x0 + SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1 + SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1 SECRETMEM_MAGIC = 0x5345434d SECURITYFS_MAGIC = 0x73636673 SEEK_CUR = 0x1 @@ -3075,6 +3108,7 @@ const ( SOL_TIPC = 0x10f SOL_TLS = 0x11a SOL_UDP = 0x11 + SOL_VSOCK = 0x11f SOL_X25 = 0x106 SOL_XDP = 0x11b SOMAXCONN = 0x1000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 4920821cf3..42ff8c3c1b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index a0c1e41127..dca436004f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -282,6 +282,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index c63985560f..5cca668ac3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -288,6 +288,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 47cc62e25c..d8cae6d153 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -278,6 +278,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 27ac4a09e2..28e39afdcb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -275,6 +275,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 54694642a5..cd66e92cb4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 3adb81d758..c1595eba78 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 2dfe98f0d1..ee9456b0da 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index f5398f84f0..8cfca81e1b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -281,6 +281,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x80 SIOCATMARK = 0x40047307 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c54f152d68..60b0deb3af 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -336,6 +336,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 76057dc72f..f90aa7281b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index e0c3725e2b..ba9e015033 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -340,6 +340,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 18f2813ed5..07cdfd6e9f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -272,6 +272,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 11619d4ec8..2f1dd214a7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -344,6 +344,9 @@ const ( SCM_TIMESTAMPNS = 0x23 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104 SFD_CLOEXEC = 0x80000 SFD_NONBLOCK = 0x800 SIOCATMARK = 0x8905 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 396d994da7..f40519d901 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -335,6 +335,9 @@ const ( SCM_TIMESTAMPNS = 0x21 SCM_TXTIME = 0x3f SCM_WIFI_STATUS = 0x25 + SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 + SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 + SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 SFD_CLOEXEC = 0x400000 SFD_NONBLOCK = 0x4000 SF_FP = 0x38 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 1488d27128..87d8612a1d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) { + _, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdents(fd int, buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index fcf3ecbdde..0cc3ce496e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -448,4 +448,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index f56dc2504a..856d92d69e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -371,4 +371,7 @@ const ( SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 974bf24676..8d467094cf 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -412,4 +412,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 39a2739e23..edc173244d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -315,4 +315,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index cf9c9d77e1..445eba2061 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -309,4 +309,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 10b7362ef4..adba01bca7 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index cd4d8b4fd3..014c4e9c7a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 2c0efca818..ccc97d74d0 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -362,4 +362,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_CACHESTAT = 5451 SYS_FCHMODAT2 = 5452 + SYS_MAP_SHADOW_STACK = 5453 + SYS_FUTEX_WAKE = 5454 + SYS_FUTEX_WAIT = 5455 + SYS_FUTEX_REQUEUE = 5456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index a72e31d391..ec2b64a95d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -432,4 +432,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_CACHESTAT = 4451 SYS_FCHMODAT2 = 4452 + SYS_MAP_SHADOW_STACK = 4453 + SYS_FUTEX_WAKE = 4454 + SYS_FUTEX_WAIT = 4455 + SYS_FUTEX_REQUEUE = 4456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index c7d1e37471..21a839e338 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -439,4 +439,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index f4d4838c87..c11121ec3b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index b64f0e5911..909b631fcb 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -411,4 +411,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 95711195a0..e49bed16ea 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -316,4 +316,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index f94e943bc4..66017d2d32 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -377,4 +377,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index ba0c2bc515..47bab18dce 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -390,4 +390,8 @@ const ( SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_CACHESTAT = 451 SYS_FCHMODAT2 = 452 + SYS_MAP_SHADOW_STACK = 453 + SYS_FUTEX_WAKE = 454 + SYS_FUTEX_WAIT = 455 + SYS_FUTEX_REQUEUE = 456 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index bbf8399ff5..eff6bcdef8 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -174,7 +174,8 @@ type FscryptPolicyV2 struct { Contents_encryption_mode uint8 Filenames_encryption_mode uint8 Flags uint8 - _ [4]uint8 + Log2_data_unit_size uint8 + _ [3]uint8 Master_key_identifier [16]uint8 } @@ -455,60 +456,63 @@ type Ucred struct { } type TCPInfo struct { - State uint8 - Ca_state uint8 - Retransmits uint8 - Probes uint8 - Backoff uint8 - Options uint8 - Rto uint32 - Ato uint32 - Snd_mss uint32 - Rcv_mss uint32 - Unacked uint32 - Sacked uint32 - Lost uint32 - Retrans uint32 - Fackets uint32 - Last_data_sent uint32 - Last_ack_sent uint32 - Last_data_recv uint32 - Last_ack_recv uint32 - Pmtu uint32 - Rcv_ssthresh uint32 - Rtt uint32 - Rttvar uint32 - Snd_ssthresh uint32 - Snd_cwnd uint32 - Advmss uint32 - Reordering uint32 - Rcv_rtt uint32 - Rcv_space uint32 - Total_retrans uint32 - Pacing_rate uint64 - Max_pacing_rate uint64 - Bytes_acked uint64 - Bytes_received uint64 - Segs_out uint32 - Segs_in uint32 - Notsent_bytes uint32 - Min_rtt uint32 - Data_segs_in uint32 - Data_segs_out uint32 - Delivery_rate uint64 - Busy_time uint64 - Rwnd_limited uint64 - Sndbuf_limited uint64 - Delivered uint32 - Delivered_ce uint32 - Bytes_sent uint64 - Bytes_retrans uint64 - Dsack_dups uint32 - Reord_seen uint32 - Rcv_ooopack uint32 - Snd_wnd uint32 - Rcv_wnd uint32 - Rehash uint32 + State uint8 + Ca_state uint8 + Retransmits uint8 + Probes uint8 + Backoff uint8 + Options uint8 + Rto uint32 + Ato uint32 + Snd_mss uint32 + Rcv_mss uint32 + Unacked uint32 + Sacked uint32 + Lost uint32 + Retrans uint32 + Fackets uint32 + Last_data_sent uint32 + Last_ack_sent uint32 + Last_data_recv uint32 + Last_ack_recv uint32 + Pmtu uint32 + Rcv_ssthresh uint32 + Rtt uint32 + Rttvar uint32 + Snd_ssthresh uint32 + Snd_cwnd uint32 + Advmss uint32 + Reordering uint32 + Rcv_rtt uint32 + Rcv_space uint32 + Total_retrans uint32 + Pacing_rate uint64 + Max_pacing_rate uint64 + Bytes_acked uint64 + Bytes_received uint64 + Segs_out uint32 + Segs_in uint32 + Notsent_bytes uint32 + Min_rtt uint32 + Data_segs_in uint32 + Data_segs_out uint32 + Delivery_rate uint64 + Busy_time uint64 + Rwnd_limited uint64 + Sndbuf_limited uint64 + Delivered uint32 + Delivered_ce uint32 + Bytes_sent uint64 + Bytes_retrans uint64 + Dsack_dups uint32 + Reord_seen uint32 + Rcv_ooopack uint32 + Snd_wnd uint32 + Rcv_wnd uint32 + Rehash uint32 + Total_rto uint16 + Total_rto_recoveries uint16 + Total_rto_time uint32 } type CanFilter struct { @@ -551,7 +555,7 @@ const ( SizeofIPv6MTUInfo = 0x20 SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc - SizeofTCPInfo = 0xf0 + SizeofTCPInfo = 0xf8 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -832,6 +836,15 @@ const ( FSPICK_EMPTY_PATH = 0x8 FSMOUNT_CLOEXEC = 0x1 + + FSCONFIG_SET_FLAG = 0x0 + FSCONFIG_SET_STRING = 0x1 + FSCONFIG_SET_BINARY = 0x2 + FSCONFIG_SET_PATH = 0x3 + FSCONFIG_SET_PATH_EMPTY = 0x4 + FSCONFIG_SET_FD = 0x5 + FSCONFIG_CMD_CREATE = 0x6 + FSCONFIG_CMD_RECONFIGURE = 0x7 ) type OpenHow struct { @@ -1546,6 +1559,7 @@ const ( IFLA_DEVLINK_PORT = 0x3e IFLA_GSO_IPV4_MAX_SIZE = 0x3f IFLA_GRO_IPV4_MAX_SIZE = 0x40 + IFLA_DPLL_PIN = 0x41 IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 IFLA_PROTO_DOWN_REASON_MASK = 0x1 IFLA_PROTO_DOWN_REASON_VALUE = 0x2 @@ -1561,6 +1575,7 @@ const ( IFLA_INET6_ICMP6STATS = 0x6 IFLA_INET6_TOKEN = 0x7 IFLA_INET6_ADDR_GEN_MODE = 0x8 + IFLA_INET6_RA_MTU = 0x9 IFLA_BR_UNSPEC = 0x0 IFLA_BR_FORWARD_DELAY = 0x1 IFLA_BR_HELLO_TIME = 0x2 @@ -1608,6 +1623,9 @@ const ( IFLA_BR_MCAST_MLD_VERSION = 0x2c IFLA_BR_VLAN_STATS_PER_PORT = 0x2d IFLA_BR_MULTI_BOOLOPT = 0x2e + IFLA_BR_MCAST_QUERIER_STATE = 0x2f + IFLA_BR_FDB_N_LEARNED = 0x30 + IFLA_BR_FDB_MAX_LEARNED = 0x31 IFLA_BRPORT_UNSPEC = 0x0 IFLA_BRPORT_STATE = 0x1 IFLA_BRPORT_PRIORITY = 0x2 @@ -1645,6 +1663,14 @@ const ( IFLA_BRPORT_BACKUP_PORT = 0x22 IFLA_BRPORT_MRP_RING_OPEN = 0x23 IFLA_BRPORT_MRP_IN_OPEN = 0x24 + IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT = 0x25 + IFLA_BRPORT_MCAST_EHT_HOSTS_CNT = 0x26 + IFLA_BRPORT_LOCKED = 0x27 + IFLA_BRPORT_MAB = 0x28 + IFLA_BRPORT_MCAST_N_GROUPS = 0x29 + IFLA_BRPORT_MCAST_MAX_GROUPS = 0x2a + IFLA_BRPORT_NEIGH_VLAN_SUPPRESS = 0x2b + IFLA_BRPORT_BACKUP_NHID = 0x2c IFLA_INFO_UNSPEC = 0x0 IFLA_INFO_KIND = 0x1 IFLA_INFO_DATA = 0x2 @@ -1666,6 +1692,9 @@ const ( IFLA_MACVLAN_MACADDR = 0x4 IFLA_MACVLAN_MACADDR_DATA = 0x5 IFLA_MACVLAN_MACADDR_COUNT = 0x6 + IFLA_MACVLAN_BC_QUEUE_LEN = 0x7 + IFLA_MACVLAN_BC_QUEUE_LEN_USED = 0x8 + IFLA_MACVLAN_BC_CUTOFF = 0x9 IFLA_VRF_UNSPEC = 0x0 IFLA_VRF_TABLE = 0x1 IFLA_VRF_PORT_UNSPEC = 0x0 @@ -1689,9 +1718,22 @@ const ( IFLA_XFRM_UNSPEC = 0x0 IFLA_XFRM_LINK = 0x1 IFLA_XFRM_IF_ID = 0x2 + IFLA_XFRM_COLLECT_METADATA = 0x3 IFLA_IPVLAN_UNSPEC = 0x0 IFLA_IPVLAN_MODE = 0x1 IFLA_IPVLAN_FLAGS = 0x2 + NETKIT_NEXT = -0x1 + NETKIT_PASS = 0x0 + NETKIT_DROP = 0x2 + NETKIT_REDIRECT = 0x7 + NETKIT_L2 = 0x0 + NETKIT_L3 = 0x1 + IFLA_NETKIT_UNSPEC = 0x0 + IFLA_NETKIT_PEER_INFO = 0x1 + IFLA_NETKIT_PRIMARY = 0x2 + IFLA_NETKIT_POLICY = 0x3 + IFLA_NETKIT_PEER_POLICY = 0x4 + IFLA_NETKIT_MODE = 0x5 IFLA_VXLAN_UNSPEC = 0x0 IFLA_VXLAN_ID = 0x1 IFLA_VXLAN_GROUP = 0x2 @@ -1722,6 +1764,8 @@ const ( IFLA_VXLAN_GPE = 0x1b IFLA_VXLAN_TTL_INHERIT = 0x1c IFLA_VXLAN_DF = 0x1d + IFLA_VXLAN_VNIFILTER = 0x1e + IFLA_VXLAN_LOCALBYPASS = 0x1f IFLA_GENEVE_UNSPEC = 0x0 IFLA_GENEVE_ID = 0x1 IFLA_GENEVE_REMOTE = 0x2 @@ -1736,6 +1780,7 @@ const ( IFLA_GENEVE_LABEL = 0xb IFLA_GENEVE_TTL_INHERIT = 0xc IFLA_GENEVE_DF = 0xd + IFLA_GENEVE_INNER_PROTO_INHERIT = 0xe IFLA_BAREUDP_UNSPEC = 0x0 IFLA_BAREUDP_PORT = 0x1 IFLA_BAREUDP_ETHERTYPE = 0x2 @@ -1748,6 +1793,8 @@ const ( IFLA_GTP_FD1 = 0x2 IFLA_GTP_PDP_HASHSIZE = 0x3 IFLA_GTP_ROLE = 0x4 + IFLA_GTP_CREATE_SOCKETS = 0x5 + IFLA_GTP_RESTART_COUNT = 0x6 IFLA_BOND_UNSPEC = 0x0 IFLA_BOND_MODE = 0x1 IFLA_BOND_ACTIVE_SLAVE = 0x2 @@ -1777,6 +1824,9 @@ const ( IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a IFLA_BOND_TLB_DYNAMIC_LB = 0x1b IFLA_BOND_PEER_NOTIF_DELAY = 0x1c + IFLA_BOND_AD_LACP_ACTIVE = 0x1d + IFLA_BOND_MISSED_MAX = 0x1e + IFLA_BOND_NS_IP6_TARGET = 0x1f IFLA_BOND_AD_INFO_UNSPEC = 0x0 IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 @@ -1792,6 +1842,7 @@ const ( IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8 + IFLA_BOND_SLAVE_PRIO = 0x9 IFLA_VF_INFO_UNSPEC = 0x0 IFLA_VF_INFO = 0x1 IFLA_VF_UNSPEC = 0x0 @@ -1850,8 +1901,16 @@ const ( IFLA_STATS_LINK_XSTATS_SLAVE = 0x3 IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4 IFLA_STATS_AF_SPEC = 0x5 + IFLA_STATS_GETSET_UNSPEC = 0x0 + IFLA_STATS_GET_FILTERS = 0x1 + IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS = 0x2 IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0 IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO = 0x2 + IFLA_OFFLOAD_XSTATS_L3_STATS = 0x3 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC = 0x0 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED = 0x2 IFLA_XDP_UNSPEC = 0x0 IFLA_XDP_FD = 0x1 IFLA_XDP_ATTACHED = 0x2 @@ -1881,6 +1940,11 @@ const ( IFLA_RMNET_UNSPEC = 0x0 IFLA_RMNET_MUX_ID = 0x1 IFLA_RMNET_FLAGS = 0x2 + IFLA_MCTP_UNSPEC = 0x0 + IFLA_MCTP_NET = 0x1 + IFLA_DSA_UNSPEC = 0x0 + IFLA_DSA_CONDUIT = 0x1 + IFLA_DSA_MASTER = 0x1 ) const ( @@ -3399,7 +3463,7 @@ const ( DEVLINK_PORT_FN_ATTR_STATE = 0x2 DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3 DEVLINK_PORT_FN_ATTR_CAPS = 0x4 - DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4 + DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5 ) type FsverityDigest struct { @@ -4183,7 +4247,8 @@ const ( ) type LandlockRulesetAttr struct { - Access_fs uint64 + Access_fs uint64 + Access_net uint64 } type LandlockPathBeneathAttr struct { @@ -5134,7 +5199,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x1b + NL80211_FREQUENCY_ATTR_MAX = 0x1c NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc @@ -5547,7 +5612,7 @@ const ( NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2 NL80211_REGDOM_TYPE_INTERSECTION = 0x3 NL80211_REGDOM_TYPE_WORLD = 0x1 - NL80211_REG_RULE_ATTR_MAX = 0x7 + NL80211_REG_RULE_ATTR_MAX = 0x8 NL80211_REKEY_DATA_AKM = 0x4 NL80211_REKEY_DATA_KCK = 0x2 NL80211_REKEY_DATA_KEK = 0x1 diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go index b8ad192506..d4577a4238 100644 --- a/vendor/golang.org/x/sys/windows/env_windows.go +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { return nil, err } defer DestroyEnvironmentBlock(block) - blockp := unsafe.Pointer(block) - for { - entry := UTF16PtrToString((*uint16)(blockp)) - if len(entry) == 0 { - break + size := unsafe.Sizeof(*block) + for *block != 0 { + // find NUL terminator + end := unsafe.Pointer(block) + for *(*uint16)(end) != 0 { + end = unsafe.Add(end, size) } - env = append(env, entry) - blockp = unsafe.Add(blockp, 2*(len(entry)+1)) + + entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size) + env = append(env, UTF16ToString(entry)) + block = (*uint16)(unsafe.Add(end, size)) } return env, nil } diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index ffb8708ccf..6395a031d4 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -125,8 +125,7 @@ func UTF16PtrToString(p *uint16) string { for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ { ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p)) } - - return string(utf16.Decode(unsafe.Slice(p, n))) + return UTF16ToString(unsafe.Slice(p, n)) } func Getpagesize() int { return 4096 } diff --git a/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go b/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go index 83774fbcbe..d5dccb9337 100644 --- a/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go +++ b/vendor/google.golang.org/genproto/googleapis/api/annotations/client.pb.go @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.21.12 +// protoc v4.24.4 // source: google/api/client.proto package annotations @@ -1033,6 +1033,18 @@ type MethodSettings struct { // total_poll_timeout: // seconds: 54000 # 90 minutes LongRunning *MethodSettings_LongRunning `protobuf:"bytes,2,opt,name=long_running,json=longRunning,proto3" json:"long_running,omitempty"` + // List of top-level fields of the request message, that should be + // automatically populated by the client libraries based on their + // (google.api.field_info).format. Currently supported format: UUID4. + // + // Example of a YAML configuration: + // + // publishing: + // method_settings: + // - selector: google.example.v1.ExampleService.CreateExample + // auto_populated_fields: + // - request_id + AutoPopulatedFields []string `protobuf:"bytes,3,rep,name=auto_populated_fields,json=autoPopulatedFields,proto3" json:"auto_populated_fields,omitempty"` } func (x *MethodSettings) Reset() { @@ -1081,6 +1093,13 @@ func (x *MethodSettings) GetLongRunning() *MethodSettings_LongRunning { return nil } +func (x *MethodSettings) GetAutoPopulatedFields() []string { + if x != nil { + return x.AutoPopulatedFields + } + return nil +} + // Describes settings to use when generating API methods that use the // long-running operation pattern. // All default values below are from those used in the client library @@ -1452,69 +1471,73 @@ var file_google_api_client_proto_rawDesc = []byte{ 0x6d, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0x8e, 0x03, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x22, 0xc2, 0x03, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x49, 0x0a, 0x0c, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, - 0x6e, 0x67, 0x52, 0x0b, 0x6c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x1a, - 0x94, 0x02, 0x0a, 0x0b, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, - 0x47, 0x0a, 0x12, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, - 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x50, - 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x6f, 0x6c, 0x6c, - 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x13, 0x70, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x6c, - 0x61, 0x79, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x0e, - 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x0c, 0x6d, 0x61, 0x78, 0x50, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x47, 0x0a, - 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x6f, 0x6c, 0x6c, 0x54, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x2a, 0xa3, 0x01, 0x0a, 0x19, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x27, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x4c, - 0x49, 0x42, 0x52, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, 0x49, 0x5a, 0x41, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x4f, 0x55, 0x44, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, - 0x41, 0x44, 0x53, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x48, 0x4f, 0x54, 0x4f, 0x53, 0x10, - 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x52, 0x45, 0x45, 0x54, 0x5f, 0x56, 0x49, 0x45, 0x57, - 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x48, 0x4f, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x05, - 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x4f, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x45, 0x4e, - 0x45, 0x52, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x49, 0x10, 0x07, 0x2a, 0x67, 0x0a, 0x18, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x44, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x26, 0x43, 0x4c, 0x49, 0x45, - 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x42, 0x52, 0x41, 0x52, 0x59, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x49, - 0x4e, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x10, 0x0a, - 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x41, - 0x47, 0x45, 0x52, 0x10, 0x14, 0x3a, 0x4a, 0x0a, 0x10, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9b, 0x08, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x3a, 0x43, 0x0a, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x68, 0x6f, 0x73, - 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x99, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x43, 0x0a, 0x0c, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x5f, - 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9a, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x6f, 0x61, 0x75, 0x74, 0x68, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x42, 0x69, 0x0a, 0x0e, 0x63, - 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0b, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, - 0x70, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xa2, - 0x02, 0x04, 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x67, 0x52, 0x0b, 0x6c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x12, + 0x32, 0x0a, 0x15, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, + 0x61, 0x75, 0x74, 0x6f, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x1a, 0x94, 0x02, 0x0a, 0x0b, 0x4c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, + 0x69, 0x6e, 0x67, 0x12, 0x47, 0x0a, 0x12, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x70, + 0x6f, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x50, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x32, 0x0a, 0x15, + 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x70, 0x6c, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x13, 0x70, 0x6f, 0x6c, + 0x6c, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x69, 0x65, 0x72, + 0x12, 0x3f, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, 0x64, 0x65, 0x6c, + 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x50, 0x6f, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x61, + 0x79, 0x12, 0x47, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x6c, 0x6c, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, + 0x6f, 0x6c, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x2a, 0xa3, 0x01, 0x0a, 0x19, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x4f, 0x72, 0x67, 0x61, + 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x27, 0x43, 0x4c, 0x49, 0x45, + 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x42, 0x52, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x47, 0x41, 0x4e, + 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x4f, 0x55, 0x44, 0x10, 0x01, + 0x12, 0x07, 0x0a, 0x03, 0x41, 0x44, 0x53, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x48, 0x4f, + 0x54, 0x4f, 0x53, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x52, 0x45, 0x45, 0x54, 0x5f, + 0x56, 0x49, 0x45, 0x57, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x48, 0x4f, 0x50, 0x50, 0x49, + 0x4e, 0x47, 0x10, 0x05, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x4f, 0x10, 0x06, 0x12, 0x11, 0x0a, + 0x0d, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x49, 0x10, 0x07, + 0x2a, 0x67, 0x0a, 0x18, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, + 0x79, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x26, + 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x42, 0x52, 0x41, 0x52, 0x59, 0x5f, 0x44, + 0x45, 0x53, 0x54, 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x49, 0x54, 0x48, + 0x55, 0x42, 0x10, 0x0a, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x5f, + 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x52, 0x10, 0x14, 0x3a, 0x4a, 0x0a, 0x10, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1e, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9b, 0x08, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x3a, 0x43, 0x0a, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x99, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x43, 0x0a, 0x0c, 0x6f, 0x61, + 0x75, 0x74, 0x68, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9a, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x42, + 0x69, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x61, 0x70, + 0x69, 0x42, 0x0b, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x41, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0xa2, 0x02, 0x04, 0x47, 0x41, 0x50, 0x49, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index e9e97d4511..856c75dd4e 100644 --- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -18,8 +18,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.22.0 +// protoc-gen-go v1.32.0 +// protoc v4.25.2 // source: grpc/binlog/v1/binarylog.proto package grpc_binarylog_v1 diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index f6e815e6bf..f0b7f3200f 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -1772,6 +1772,8 @@ func parseTarget(target string) (resolver.Target, error) { return resolver.Target{URL: *u}, nil } +// encodeAuthority escapes the authority string based on valid chars defined in +// https://datatracker.ietf.org/doc/html/rfc3986#section-3.2. func encodeAuthority(authority string) string { const upperhex = "0123456789ABCDEF" diff --git a/vendor/google.golang.org/grpc/encoding/proto/proto.go b/vendor/google.golang.org/grpc/encoding/proto/proto.go index 0ee3d3bae9..66d5cdf03e 100644 --- a/vendor/google.golang.org/grpc/encoding/proto/proto.go +++ b/vendor/google.golang.org/grpc/encoding/proto/proto.go @@ -23,8 +23,9 @@ package proto import ( "fmt" - "github.com/golang/protobuf/proto" "google.golang.org/grpc/encoding" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/protoadapt" ) // Name is the name registered for the proto compressor. @@ -38,21 +39,34 @@ func init() { type codec struct{} func (codec) Marshal(v any) ([]byte, error) { - vv, ok := v.(proto.Message) - if !ok { + vv := messageV2Of(v) + if vv == nil { return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v) } + return proto.Marshal(vv) } func (codec) Unmarshal(data []byte, v any) error { - vv, ok := v.(proto.Message) - if !ok { + vv := messageV2Of(v) + if vv == nil { return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v) } + return proto.Unmarshal(data, vv) } +func messageV2Of(v any) proto.Message { + switch v := v.(type) { + case protoadapt.MessageV1: + return protoadapt.MessageV2Of(v) + case protoadapt.MessageV2: + return v + } + + return nil +} + func (codec) Name() string { return Name } diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go index 24299efd63..5bf880d419 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go @@ -17,8 +17,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.22.0 +// protoc-gen-go v1.32.0 +// protoc v4.25.2 // source: grpc/health/v1/health.proto package grpc_health_v1 diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go index 4439cda0f3..4c46c098dc 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.22.0 +// - protoc v4.25.2 // source: grpc/health/v1/health.proto package grpc_health_v1 diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index 0f31274a3c..e8456a77c2 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -25,11 +25,12 @@ import ( "sync/atomic" "time" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" ) type callIDGenerator struct { @@ -88,7 +89,7 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { // in TruncatingMethodLogger as possible. func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *binlogpb.GrpcLogEntry { m := c.toProto() - timestamp, _ := ptypes.TimestampProto(time.Now()) + timestamp := timestamppb.Now() m.Timestamp = timestamp m.CallId = ml.callID m.SequenceIdWithinCall = ml.idWithinCallGen.next() @@ -178,7 +179,7 @@ func (c *ClientHeader) toProto() *binlogpb.GrpcLogEntry { Authority: c.Authority, } if c.Timeout > 0 { - clientHeader.Timeout = ptypes.DurationProto(c.Timeout) + clientHeader.Timeout = durationpb.New(c.Timeout) } ret := &binlogpb.GrpcLogEntry{ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER, diff --git a/vendor/google.golang.org/grpc/internal/binarylog/sink.go b/vendor/google.golang.org/grpc/internal/binarylog/sink.go index 264de387c2..9ea598b14c 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/sink.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/sink.go @@ -25,8 +25,8 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1" + "google.golang.org/protobuf/proto" ) var ( diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go index aa97273e7d..0126d6b510 100644 --- a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go +++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go @@ -1,3 +1,8 @@ +//go:build !go1.21 + +// TODO: when this file is deleted (after Go 1.20 support is dropped), delete +// all of grpcrand and call the rand package directly. + /* * * Copyright 2018 gRPC authors. diff --git a/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go new file mode 100644 index 0000000000..c37299af1e --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/grpcrand/grpcrand_go1.21.go @@ -0,0 +1,73 @@ +//go:build go1.21 + +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package grpcrand implements math/rand functions in a concurrent-safe way +// with a global random source, independent of math/rand's global source. +package grpcrand + +import "math/rand" + +// This implementation will be used for Go version 1.21 or newer. +// For older versions, the original implementation with mutex will be used. + +// Int implements rand.Int on the grpcrand global source. +func Int() int { + return rand.Int() +} + +// Int63n implements rand.Int63n on the grpcrand global source. +func Int63n(n int64) int64 { + return rand.Int63n(n) +} + +// Intn implements rand.Intn on the grpcrand global source. +func Intn(n int) int { + return rand.Intn(n) +} + +// Int31n implements rand.Int31n on the grpcrand global source. +func Int31n(n int32) int32 { + return rand.Int31n(n) +} + +// Float64 implements rand.Float64 on the grpcrand global source. +func Float64() float64 { + return rand.Float64() +} + +// Uint64 implements rand.Uint64 on the grpcrand global source. +func Uint64() uint64 { + return rand.Uint64() +} + +// Uint32 implements rand.Uint32 on the grpcrand global source. +func Uint32() uint32 { + return rand.Uint32() +} + +// ExpFloat64 implements rand.ExpFloat64 on the grpcrand global source. +func ExpFloat64() float64 { + return rand.ExpFloat64() +} + +// Shuffle implements rand.Shuffle on the grpcrand global source. +var Shuffle = func(n int, f func(int, int)) { + rand.Shuffle(n, f) +} diff --git a/vendor/google.golang.org/grpc/internal/pretty/pretty.go b/vendor/google.golang.org/grpc/internal/pretty/pretty.go index 7033191375..52cfab1b93 100644 --- a/vendor/google.golang.org/grpc/internal/pretty/pretty.go +++ b/vendor/google.golang.org/grpc/internal/pretty/pretty.go @@ -24,7 +24,6 @@ import ( "encoding/json" "fmt" - "github.com/golang/protobuf/jsonpb" protov1 "github.com/golang/protobuf/proto" "google.golang.org/protobuf/encoding/protojson" protov2 "google.golang.org/protobuf/proto" @@ -38,15 +37,15 @@ const jsonIndent = " " func ToJSON(e any) string { switch ee := e.(type) { case protov1.Message: - mm := jsonpb.Marshaler{Indent: jsonIndent} - ret, err := mm.MarshalToString(ee) + mm := protojson.MarshalOptions{Indent: jsonIndent} + ret, err := mm.Marshal(protov1.MessageV2(ee)) if err != nil { // This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2 // messages are not imported, and this will fail because the message // is not found. return fmt.Sprintf("%+v", ee) } - return ret + return string(ret) case protov2.Message: mm := protojson.MarshalOptions{ Multiline: true, diff --git a/vendor/google.golang.org/grpc/internal/status/status.go b/vendor/google.golang.org/grpc/internal/status/status.go index 03ef2fedd5..c7dbc82059 100644 --- a/vendor/google.golang.org/grpc/internal/status/status.go +++ b/vendor/google.golang.org/grpc/internal/status/status.go @@ -31,10 +31,11 @@ import ( "errors" "fmt" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" spb "google.golang.org/genproto/googleapis/rpc/status" "google.golang.org/grpc/codes" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/protoadapt" + "google.golang.org/protobuf/types/known/anypb" ) // Status represents an RPC status code, message, and details. It is immutable @@ -130,14 +131,14 @@ func (s *Status) Err() error { // WithDetails returns a new status with the provided details messages appended to the status. // If any errors are encountered, it returns nil and the first error encountered. -func (s *Status) WithDetails(details ...proto.Message) (*Status, error) { +func (s *Status) WithDetails(details ...protoadapt.MessageV1) (*Status, error) { if s.Code() == codes.OK { return nil, errors.New("no error details for status with code OK") } // s.Code() != OK implies that s.Proto() != nil. p := s.Proto() for _, detail := range details { - any, err := ptypes.MarshalAny(detail) + any, err := anypb.New(protoadapt.MessageV2Of(detail)) if err != nil { return nil, err } @@ -154,12 +155,12 @@ func (s *Status) Details() []any { } details := make([]any, 0, len(s.s.Details)) for _, any := range s.s.Details { - detail := &ptypes.DynamicAny{} - if err := ptypes.UnmarshalAny(any, detail); err != nil { + detail, err := any.UnmarshalNew() + if err != nil { details = append(details, err) continue } - details = append(details, detail.Message) + details = append(details, detail) } return details } diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index b330ccedc8..83c3829826 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -535,8 +535,8 @@ const minBatchSize = 1000 // size is too low to give stream goroutines a chance to fill it up. // // Upon exiting, if the error causing the exit is not an I/O error, run() -// flushes and closes the underlying connection. Otherwise, the connection is -// left open to allow the I/O error to be encountered by the reader instead. +// flushes the underlying connection. The connection is always left open to +// allow different closing behavior on the client and server. func (l *loopyWriter) run() (err error) { defer func() { if l.logger.V(logLevel) { @@ -544,7 +544,6 @@ func (l *loopyWriter) run() (err error) { } if !isIOError(err) { l.framer.writer.Flush() - l.conn.Close() } l.cbuf.finish() }() diff --git a/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/vendor/google.golang.org/grpc/internal/transport/handler_server.go index a9d70e2a16..bd39ff9a22 100644 --- a/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -35,7 +35,6 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" "golang.org/x/net/http2" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -45,6 +44,7 @@ import ( "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" ) // NewServerHandlerTransport returns a ServerTransport handling gRPC from diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index c33ac5961b..eff8799640 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -451,7 +451,13 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } go func() { t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) - t.loopy.run() + if err := t.loopy.run(); !isIOError(err) { + // Immediately close the connection, as the loopy writer returns + // when there are no more active streams and we were draining (the + // server sent a GOAWAY). For I/O errors, the reader will hit it + // after draining any remaining incoming data. + t.conn.Close() + } close(t.writerDone) }() return t, nil diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index f6bac0e8a0..3839c1ade2 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -32,13 +32,13 @@ import ( "sync/atomic" "time" - "github.com/golang/protobuf/proto" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/internal/syscall" + "google.golang.org/protobuf/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -322,8 +322,24 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, go func() { t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler - t.loopy.run() + err := t.loopy.run() close(t.loopyWriterDone) + if !isIOError(err) { + // Close the connection if a non-I/O error occurs (for I/O errors + // the reader will also encounter the error and close). Wait 1 + // second before closing the connection, or when the reader is done + // (i.e. the client already closed the connection or a connection + // error occurred). This avoids the potential problem where there + // is unread data on the receive side of the connection, which, if + // closed, would lead to a TCP RST instead of FIN, and the client + // encountering errors. For more info: + // https://github.com/grpc/grpc-go/issues/5358 + select { + case <-t.readerDone: + case <-time.After(time.Second): + } + t.conn.Close() + } }() go t.keepalive() return t, nil @@ -609,8 +625,8 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade // traceCtx attaches trace to ctx and returns the new context. func (t *http2Server) HandleStreams(ctx context.Context, handle func(*Stream)) { defer func() { - <-t.loopyWriterDone close(t.readerDone) + <-t.loopyWriterDone }() for { t.controlBuf.throttle() @@ -636,10 +652,6 @@ func (t *http2Server) HandleStreams(ctx context.Context, handle func(*Stream)) { } continue } - if err == io.EOF || err == io.ErrUnexpectedEOF { - t.Close(err) - return - } t.Close(err) return } @@ -1329,6 +1341,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { if err := t.framer.fr.WriteGoAway(sid, g.code, g.debugData); err != nil { return false, err } + t.framer.writer.Flush() if retErr != nil { return false, retErr } @@ -1349,7 +1362,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) { return false, err } go func() { - timer := time.NewTimer(time.Minute) + timer := time.NewTimer(5 * time.Second) defer timer.Stop() select { case <-t.drainEvent.Done(): diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index b7b8fec180..d3796c256e 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -28,6 +28,7 @@ import ( "fmt" "io" "net" + "strings" "sync" "sync/atomic" "time" @@ -362,8 +363,12 @@ func (s *Stream) SendCompress() string { // ClientAdvertisedCompressors returns the compressor names advertised by the // client via grpc-accept-encoding header. -func (s *Stream) ClientAdvertisedCompressors() string { - return s.clientAdvertisedCompressors +func (s *Stream) ClientAdvertisedCompressors() []string { + values := strings.Split(s.clientAdvertisedCompressors, ",") + for i, v := range values { + values[i] = strings.TrimSpace(v) + } + return values } // Done returns a channel which is closed when it receives the final status diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index adf89dd9cf..d72f21c1b3 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -168,6 +168,9 @@ type BuildOptions struct { // field. In most cases though, it is not appropriate, and this field may // be ignored. Dialer func(context.Context, string) (net.Conn, error) + // Authority is the effective authority of the clientconn for which the + // resolver is built. + Authority string } // An Endpoint is one network endpoint, or server, which may have multiple diff --git a/vendor/google.golang.org/grpc/resolver_wrapper.go b/vendor/google.golang.org/grpc/resolver_wrapper.go index c79bab1214..f845ac9589 100644 --- a/vendor/google.golang.org/grpc/resolver_wrapper.go +++ b/vendor/google.golang.org/grpc/resolver_wrapper.go @@ -75,6 +75,7 @@ func (ccr *ccResolverWrapper) start() error { DialCreds: ccr.cc.dopts.copts.TransportCredentials, CredsBundle: ccr.cc.dopts.copts.CredsBundle, Dialer: ccr.cc.dopts.copts.Dialer, + Authority: ccr.cc.authority, } var err error ccr.resolver, err = ccr.cc.resolverBuilder.Build(ccr.cc.parsedTarget, ccr, opts) diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index a4b6bc6873..82493d237b 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -189,6 +189,20 @@ type EmptyCallOption struct{} func (EmptyCallOption) before(*callInfo) error { return nil } func (EmptyCallOption) after(*callInfo, *csAttempt) {} +// StaticMethod returns a CallOption which specifies that a call is being made +// to a method that is static, which means the method is known at compile time +// and doesn't change at runtime. This can be used as a signal to stats plugins +// that this method is safe to include as a key to a measurement. +func StaticMethod() CallOption { + return StaticMethodCallOption{} +} + +// StaticMethodCallOption is a CallOption that specifies that a call comes +// from a static method. +type StaticMethodCallOption struct { + EmptyCallOption +} + // Header returns a CallOptions that retrieves the header metadata // for a unary RPC. func Header(md *metadata.MD) CallOption { @@ -730,17 +744,19 @@ type payloadInfo struct { uncompressedBytes []byte } -func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) ([]byte, error) { - pf, buf, err := p.recvMsg(maxReceiveMessageSize) +// recvAndDecompress reads a message from the stream, decompressing it if necessary. +// +// Cancelling the returned cancel function releases the buffer back to the pool. So the caller should cancel as soon as +// the buffer is no longer needed. +func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor, +) (uncompressedBuf []byte, cancel func(), err error) { + pf, compressedBuf, err := p.recvMsg(maxReceiveMessageSize) if err != nil { - return nil, err - } - if payInfo != nil { - payInfo.compressedLength = len(buf) + return nil, nil, err } if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil { - return nil, st.Err() + return nil, nil, st.Err() } var size int @@ -748,21 +764,35 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei // To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor, // use this decompressor as the default. if dc != nil { - buf, err = dc.Do(bytes.NewReader(buf)) - size = len(buf) + uncompressedBuf, err = dc.Do(bytes.NewReader(compressedBuf)) + size = len(uncompressedBuf) } else { - buf, size, err = decompress(compressor, buf, maxReceiveMessageSize) + uncompressedBuf, size, err = decompress(compressor, compressedBuf, maxReceiveMessageSize) } if err != nil { - return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) + return nil, nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) } if size > maxReceiveMessageSize { // TODO: Revisit the error code. Currently keep it consistent with java // implementation. - return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) + return nil, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) } + } else { + uncompressedBuf = compressedBuf } - return buf, nil + + if payInfo != nil { + payInfo.compressedLength = len(compressedBuf) + payInfo.uncompressedBytes = uncompressedBuf + + cancel = func() {} + } else { + cancel = func() { + p.recvBufferPool.Put(&compressedBuf) + } + } + + return uncompressedBuf, cancel, nil } // Using compressor, decompress d, returning data and size. @@ -782,6 +812,9 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize // size is used as an estimate to size the buffer, but we // will read more data if available. // +MinRead so ReadFrom will not reallocate if size is correct. + // + // TODO: If we ensure that the buffer size is the same as the DecompressedSize, + // we can also utilize the recv buffer pool here. buf := bytes.NewBuffer(make([]byte, 0, size+bytes.MinRead)) bytesRead, err := buf.ReadFrom(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) return buf.Bytes(), int(bytesRead), err @@ -797,18 +830,15 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize // dc takes precedence over compressor. // TODO(dfawley): wrap the old compressor/decompressor using the new API? func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error { - buf, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) + buf, cancel, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) if err != nil { return err } + defer cancel() + if err := c.Unmarshal(buf, m); err != nil { return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err) } - if payInfo != nil { - payInfo.uncompressedBytes = buf - } else { - p.recvBufferPool.Put(&buf) - } return nil } @@ -958,6 +988,7 @@ const ( SupportPackageIsVersion5 = true SupportPackageIsVersion6 = true SupportPackageIsVersion7 = true + SupportPackageIsVersion8 = true ) const grpcUA = "grpc-go/" + Version diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index e89c5ac613..a6a11704b3 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -33,8 +33,6 @@ import ( "sync/atomic" "time" - "golang.org/x/net/trace" - "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" "google.golang.org/grpc/encoding" @@ -131,7 +129,7 @@ type Server struct { drain bool cv *sync.Cond // signaled when connections close for GracefulStop services map[string]*serviceInfo // service name -> service info - events trace.EventLog + events traceEventLog quit *grpcsync.Event done *grpcsync.Event @@ -670,7 +668,7 @@ func NewServer(opt ...ServerOption) *Server { s.cv = sync.NewCond(&s.mu) if EnableTracing { _, file, line, _ := runtime.Caller(1) - s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) + s.events = newTraceEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) } if s.opts.numServerWorkers > 0 { @@ -1344,7 +1342,8 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor if len(shs) != 0 || len(binlogs) != 0 { payInfo = &payloadInfo{} } - d, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) + + d, cancel, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) if err != nil { if e := t.WriteStatus(stream, status.Convert(err)); e != nil { channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e) @@ -1355,6 +1354,8 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor t.IncrMsgRecv() } df := func(v any) error { + defer cancel() + if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil { return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err) } @@ -1734,8 +1735,8 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str ctx = contextWithServer(ctx, s) var ti *traceInfo if EnableTracing { - tr := trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) - ctx = trace.NewContext(ctx, tr) + tr := newTrace("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) + ctx = newTraceContext(ctx, tr) ti = &traceInfo{ tr: tr, firstLine: firstLine{ @@ -2119,7 +2120,7 @@ func ClientSupportedCompressors(ctx context.Context) ([]string, error) { return nil, fmt.Errorf("failed to fetch the stream from the given context %v", ctx) } - return strings.Split(stream.ClientAdvertisedCompressors(), ","), nil + return stream.ClientAdvertisedCompressors(), nil } // SetTrailer sets the trailer metadata that will be sent when an RPC returns. @@ -2159,7 +2160,7 @@ func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric { // validateSendCompressor returns an error when given compressor name cannot be // handled by the server or the client based on the advertised compressors. -func validateSendCompressor(name, clientCompressors string) error { +func validateSendCompressor(name string, clientCompressors []string) error { if name == encoding.Identity { return nil } @@ -2168,7 +2169,7 @@ func validateSendCompressor(name, clientCompressors string) error { return fmt.Errorf("compressor not registered %q", name) } - for _, c := range strings.Split(clientCompressors, ",") { + for _, c := range clientCompressors { if c == name { return nil // found match } diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index d621f52b1a..814e998354 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -27,7 +27,6 @@ import ( "sync" "time" - "golang.org/x/net/trace" "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" "google.golang.org/grpc/encoding" @@ -431,7 +430,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error) var trInfo *traceInfo if EnableTracing { trInfo = &traceInfo{ - tr: trace.New("grpc.Sent."+methodFamily(method), method), + tr: newTrace("grpc.Sent."+methodFamily(method), method), firstLine: firstLine{ client: true, }, @@ -440,7 +439,7 @@ func (cs *clientStream) newAttemptLocked(isTransparent bool) (*csAttempt, error) trInfo.firstLine.deadline = time.Until(deadline) } trInfo.tr.LazyLog(&trInfo.firstLine, false) - ctx = trace.NewContext(ctx, trInfo.tr) + ctx = newTraceContext(ctx, trInfo.tr) } if cs.cc.parsedTarget.URL.Scheme == internal.GRPCResolverSchemeExtraMetadata { diff --git a/vendor/google.golang.org/grpc/trace.go b/vendor/google.golang.org/grpc/trace.go index 9ded79321b..10f4f798f5 100644 --- a/vendor/google.golang.org/grpc/trace.go +++ b/vendor/google.golang.org/grpc/trace.go @@ -26,8 +26,6 @@ import ( "strings" "sync" "time" - - "golang.org/x/net/trace" ) // EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package. @@ -44,9 +42,31 @@ func methodFamily(m string) string { return m } +// traceEventLog mirrors golang.org/x/net/trace.EventLog. +// +// It exists in order to avoid importing x/net/trace on grpcnotrace builds. +type traceEventLog interface { + Printf(format string, a ...any) + Errorf(format string, a ...any) + Finish() +} + +// traceLog mirrors golang.org/x/net/trace.Trace. +// +// It exists in order to avoid importing x/net/trace on grpcnotrace builds. +type traceLog interface { + LazyLog(x fmt.Stringer, sensitive bool) + LazyPrintf(format string, a ...any) + SetError() + SetRecycler(f func(any)) + SetTraceInfo(traceID, spanID uint64) + SetMaxEvents(m int) + Finish() +} + // traceInfo contains tracing information for an RPC. type traceInfo struct { - tr trace.Trace + tr traceLog firstLine firstLine } diff --git a/vendor/google.golang.org/grpc/trace_notrace.go b/vendor/google.golang.org/grpc/trace_notrace.go new file mode 100644 index 0000000000..1da3a2308e --- /dev/null +++ b/vendor/google.golang.org/grpc/trace_notrace.go @@ -0,0 +1,52 @@ +//go:build grpcnotrace + +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package grpc + +// grpcnotrace can be used to avoid importing golang.org/x/net/trace, which in +// turn enables binaries using gRPC-Go for dead code elimination, which can +// yield 10-15% improvements in binary size when tracing is not needed. + +import ( + "context" + "fmt" +) + +type notrace struct{} + +func (notrace) LazyLog(x fmt.Stringer, sensitive bool) {} +func (notrace) LazyPrintf(format string, a ...any) {} +func (notrace) SetError() {} +func (notrace) SetRecycler(f func(any)) {} +func (notrace) SetTraceInfo(traceID, spanID uint64) {} +func (notrace) SetMaxEvents(m int) {} +func (notrace) Finish() {} + +func newTrace(family, title string) traceLog { + return notrace{} +} + +func newTraceContext(ctx context.Context, tr traceLog) context.Context { + return ctx +} + +func newTraceEventLog(family, title string) traceEventLog { + return nil +} diff --git a/vendor/google.golang.org/grpc/trace_withtrace.go b/vendor/google.golang.org/grpc/trace_withtrace.go new file mode 100644 index 0000000000..88d6e8571e --- /dev/null +++ b/vendor/google.golang.org/grpc/trace_withtrace.go @@ -0,0 +1,39 @@ +//go:build !grpcnotrace + +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package grpc + +import ( + "context" + + t "golang.org/x/net/trace" +) + +func newTrace(family, title string) traceLog { + return t.New(family, title) +} + +func newTraceContext(ctx context.Context, tr traceLog) context.Context { + return t.NewContext(ctx, tr) +} + +func newTraceEventLog(family, title string) traceEventLog { + return t.NewEventLog(family, title) +} diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 1ad1ba2ad6..46ad8113ff 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.61.0" +const Version = "1.62.1" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index 5da38a4099..7a33c215b5 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -41,7 +41,7 @@ if [[ "$1" = "-install" ]]; then popd if [[ -z "${VET_SKIP_PROTO}" ]]; then if [[ "${GITHUB_ACTIONS}" = "true" ]]; then - PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files. + PROTOBUF_VERSION=25.2 # a.k.a. v4.22.0 in pb.go files. PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip pushd /home/runner/go wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} diff --git a/vendor/google.golang.org/protobuf/protoadapt/convert.go b/vendor/google.golang.org/protobuf/protoadapt/convert.go new file mode 100644 index 0000000000..ea276d15a0 --- /dev/null +++ b/vendor/google.golang.org/protobuf/protoadapt/convert.go @@ -0,0 +1,31 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package protoadapt bridges the original and new proto APIs. +package protoadapt + +import ( + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/runtime/protoimpl" +) + +// MessageV1 is the original [github.com/golang/protobuf/proto.Message] type. +type MessageV1 = protoiface.MessageV1 + +// MessageV2 is the [google.golang.org/protobuf/proto.Message] type used by the +// current [google.golang.org/protobuf] module, adding support for reflection. +type MessageV2 = proto.Message + +// MessageV1Of converts a v2 message to a v1 message. +// It returns nil if m is nil. +func MessageV1Of(m MessageV2) MessageV1 { + return protoimpl.X.ProtoMessageV1Of(m) +} + +// MessageV2Of converts a v1 message to a v2 message. +// It returns nil if m is nil. +func MessageV2Of(m MessageV1) MessageV2 { + return protoimpl.X.ProtoMessageV2Of(m) +} diff --git a/vendor/k8s.io/klog/v2/.golangci.yaml b/vendor/k8s.io/klog/v2/.golangci.yaml new file mode 100644 index 0000000000..0d77d65f06 --- /dev/null +++ b/vendor/k8s.io/klog/v2/.golangci.yaml @@ -0,0 +1,6 @@ +linters: + disable-all: true + enable: # sorted alphabetical + - gofmt + - misspell + - revive diff --git a/vendor/k8s.io/klog/v2/internal/buffer/buffer.go b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go index f325ded5e9..46de00fb06 100644 --- a/vendor/k8s.io/klog/v2/internal/buffer/buffer.go +++ b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go @@ -30,14 +30,16 @@ import ( var ( // Pid is inserted into log headers. Can be overridden for tests. Pid = os.Getpid() + + // Time, if set, will be used instead of the actual current time. + Time *time.Time ) // Buffer holds a single byte.Buffer for reuse. The zero value is ready for // use. It also provides some helper methods for output formatting. type Buffer struct { bytes.Buffer - Tmp [64]byte // temporary byte array for creating headers. - next *Buffer + Tmp [64]byte // temporary byte array for creating headers. } var buffers = sync.Pool{ @@ -122,6 +124,9 @@ func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. // It's worth about 3X. Fprintf is hard. + if Time != nil { + now = *Time + } _, month, day := now.Date() hour, minute, second := now.Clock() // Lmmdd hh:mm:ss.uuuuuu threadid file:line] @@ -157,6 +162,9 @@ func (buf *Buffer) SprintHeader(s severity.Severity, now time.Time) string { // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. // It's worth about 3X. Fprintf is hard. + if Time != nil { + now = *Time + } _, month, day := now.Date() hour, minute, second := now.Clock() // Lmmdd hh:mm:ss.uuuuuu threadid file:line] diff --git a/vendor/k8s.io/klog/v2/internal/clock/clock.go b/vendor/k8s.io/klog/v2/internal/clock/clock.go index b8b6af5c81..cc11bb4802 100644 --- a/vendor/k8s.io/klog/v2/internal/clock/clock.go +++ b/vendor/k8s.io/klog/v2/internal/clock/clock.go @@ -39,16 +39,6 @@ type Clock interface { // Sleep sleeps for the provided duration d. // Consider making the sleep interruptible by using 'select' on a context channel and a timer channel. Sleep(d time.Duration) - // Tick returns the channel of a new Ticker. - // This method does not allow to free/GC the backing ticker. Use - // NewTicker from WithTicker instead. - Tick(d time.Duration) <-chan time.Time -} - -// WithTicker allows for injecting fake or real clocks into code that -// needs to do arbitrary things based on time. -type WithTicker interface { - Clock // NewTicker returns a new Ticker. NewTicker(time.Duration) Ticker } @@ -66,7 +56,7 @@ type WithDelayedExecution interface { // WithTickerAndDelayedExecution allows for injecting fake or real clocks // into code that needs Ticker and AfterFunc functionality type WithTickerAndDelayedExecution interface { - WithTicker + Clock // AfterFunc executes f in its own goroutine after waiting // for d duration and returns a Timer whose channel can be // closed by calling Stop() on the Timer. @@ -79,7 +69,7 @@ type Ticker interface { Stop() } -var _ = WithTicker(RealClock{}) +var _ Clock = RealClock{} // RealClock really calls time.Now() type RealClock struct{} @@ -115,13 +105,6 @@ func (RealClock) AfterFunc(d time.Duration, f func()) Timer { } } -// Tick is the same as time.Tick(d) -// This method does not allow to free/GC the backing ticker. Use -// NewTicker instead. -func (RealClock) Tick(d time.Duration) <-chan time.Time { - return time.Tick(d) -} - // NewTicker returns a new Ticker. func (RealClock) NewTicker(d time.Duration) Ticker { return &realTicker{ diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go index bcdf5f8ee1..d1a4751c94 100644 --- a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go @@ -172,73 +172,6 @@ func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { Formatter{}.KVListFormat(b, keysAndValues...) } -// KVFormat serializes one key/value pair into the provided buffer. -// A space gets inserted before the pair. -func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { - b.WriteByte(' ') - // Keys are assumed to be well-formed according to - // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments - // for the sake of performance. Keys with spaces, - // special characters, etc. will break parsing. - if sK, ok := k.(string); ok { - // Avoid one allocation when the key is a string, which - // normally it should be. - b.WriteString(sK) - } else { - b.WriteString(fmt.Sprintf("%s", k)) - } - - // The type checks are sorted so that more frequently used ones - // come first because that is then faster in the common - // cases. In Kubernetes, ObjectRef (a Stringer) is more common - // than plain strings - // (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235). - switch v := v.(type) { - case textWriter: - writeTextWriterValue(b, v) - case fmt.Stringer: - writeStringValue(b, StringerToString(v)) - case string: - writeStringValue(b, v) - case error: - writeStringValue(b, ErrorToString(v)) - case logr.Marshaler: - value := MarshalerToValue(v) - // A marshaler that returns a string is useful for - // delayed formatting of complex values. We treat this - // case like a normal string. This is useful for - // multi-line support. - // - // We could do this by recursively formatting a value, - // but that comes with the risk of infinite recursion - // if a marshaler returns itself. Instead we call it - // only once and rely on it returning the intended - // value directly. - switch value := value.(type) { - case string: - writeStringValue(b, value) - default: - f.formatAny(b, value) - } - case []byte: - // In https://github.com/kubernetes/klog/pull/237 it was decided - // to format byte slices with "%+q". The advantages of that are: - // - readable output if the bytes happen to be printable - // - non-printable bytes get represented as unicode escape - // sequences (\uxxxx) - // - // The downsides are that we cannot use the faster - // strconv.Quote here and that multi-line output is not - // supported. If developers know that a byte array is - // printable and they want multi-line output, they can - // convert the value to string before logging it. - b.WriteByte('=') - b.WriteString(fmt.Sprintf("%+q", v)) - default: - f.formatAny(b, v) - } -} - func KVFormat(b *bytes.Buffer, k, v interface{}) { Formatter{}.KVFormat(b, k, v) } @@ -251,6 +184,10 @@ func (f Formatter) formatAny(b *bytes.Buffer, v interface{}) { b.WriteString(f.AnyToStringHook(v)) return } + formatAsJSON(b, v) +} + +func formatAsJSON(b *bytes.Buffer, v interface{}) { encoder := json.NewEncoder(b) l := b.Len() if err := encoder.Encode(v); err != nil { diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go new file mode 100644 index 0000000000..d9c7d15467 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_no_slog.go @@ -0,0 +1,97 @@ +//go:build !go1.21 +// +build !go1.21 + +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package serialize + +import ( + "bytes" + "fmt" + + "github.com/go-logr/logr" +) + +// KVFormat serializes one key/value pair into the provided buffer. +// A space gets inserted before the pair. +func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { + // This is the version without slog support. Must be kept in sync with + // the version in keyvalues_slog.go. + + b.WriteByte(' ') + // Keys are assumed to be well-formed according to + // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments + // for the sake of performance. Keys with spaces, + // special characters, etc. will break parsing. + if sK, ok := k.(string); ok { + // Avoid one allocation when the key is a string, which + // normally it should be. + b.WriteString(sK) + } else { + b.WriteString(fmt.Sprintf("%s", k)) + } + + // The type checks are sorted so that more frequently used ones + // come first because that is then faster in the common + // cases. In Kubernetes, ObjectRef (a Stringer) is more common + // than plain strings + // (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235). + switch v := v.(type) { + case textWriter: + writeTextWriterValue(b, v) + case fmt.Stringer: + writeStringValue(b, StringerToString(v)) + case string: + writeStringValue(b, v) + case error: + writeStringValue(b, ErrorToString(v)) + case logr.Marshaler: + value := MarshalerToValue(v) + // A marshaler that returns a string is useful for + // delayed formatting of complex values. We treat this + // case like a normal string. This is useful for + // multi-line support. + // + // We could do this by recursively formatting a value, + // but that comes with the risk of infinite recursion + // if a marshaler returns itself. Instead we call it + // only once and rely on it returning the intended + // value directly. + switch value := value.(type) { + case string: + writeStringValue(b, value) + default: + f.formatAny(b, value) + } + case []byte: + // In https://github.com/kubernetes/klog/pull/237 it was decided + // to format byte slices with "%+q". The advantages of that are: + // - readable output if the bytes happen to be printable + // - non-printable bytes get represented as unicode escape + // sequences (\uxxxx) + // + // The downsides are that we cannot use the faster + // strconv.Quote here and that multi-line output is not + // supported. If developers know that a byte array is + // printable and they want multi-line output, they can + // convert the value to string before logging it. + b.WriteByte('=') + b.WriteString(fmt.Sprintf("%+q", v)) + default: + f.formatAny(b, v) + } +} diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go new file mode 100644 index 0000000000..89acf97723 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues_slog.go @@ -0,0 +1,155 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package serialize + +import ( + "bytes" + "fmt" + "log/slog" + "strconv" + + "github.com/go-logr/logr" +) + +// KVFormat serializes one key/value pair into the provided buffer. +// A space gets inserted before the pair. +func (f Formatter) KVFormat(b *bytes.Buffer, k, v interface{}) { + // This is the version without slog support. Must be kept in sync with + // the version in keyvalues_slog.go. + + b.WriteByte(' ') + // Keys are assumed to be well-formed according to + // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments + // for the sake of performance. Keys with spaces, + // special characters, etc. will break parsing. + if sK, ok := k.(string); ok { + // Avoid one allocation when the key is a string, which + // normally it should be. + b.WriteString(sK) + } else { + b.WriteString(fmt.Sprintf("%s", k)) + } + + // The type checks are sorted so that more frequently used ones + // come first because that is then faster in the common + // cases. In Kubernetes, ObjectRef (a Stringer) is more common + // than plain strings + // (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235). + // + // slog.LogValuer does not need to be handled here because the handler will + // already have resolved such special values to the final value for logging. + switch v := v.(type) { + case textWriter: + writeTextWriterValue(b, v) + case slog.Value: + // This must come before fmt.Stringer because slog.Value implements + // fmt.Stringer, but does not produce the output that we want. + b.WriteByte('=') + generateJSON(b, v) + case fmt.Stringer: + writeStringValue(b, StringerToString(v)) + case string: + writeStringValue(b, v) + case error: + writeStringValue(b, ErrorToString(v)) + case logr.Marshaler: + value := MarshalerToValue(v) + // A marshaler that returns a string is useful for + // delayed formatting of complex values. We treat this + // case like a normal string. This is useful for + // multi-line support. + // + // We could do this by recursively formatting a value, + // but that comes with the risk of infinite recursion + // if a marshaler returns itself. Instead we call it + // only once and rely on it returning the intended + // value directly. + switch value := value.(type) { + case string: + writeStringValue(b, value) + default: + f.formatAny(b, value) + } + case slog.LogValuer: + value := slog.AnyValue(v).Resolve() + if value.Kind() == slog.KindString { + writeStringValue(b, value.String()) + } else { + b.WriteByte('=') + generateJSON(b, value) + } + case []byte: + // In https://github.com/kubernetes/klog/pull/237 it was decided + // to format byte slices with "%+q". The advantages of that are: + // - readable output if the bytes happen to be printable + // - non-printable bytes get represented as unicode escape + // sequences (\uxxxx) + // + // The downsides are that we cannot use the faster + // strconv.Quote here and that multi-line output is not + // supported. If developers know that a byte array is + // printable and they want multi-line output, they can + // convert the value to string before logging it. + b.WriteByte('=') + b.WriteString(fmt.Sprintf("%+q", v)) + default: + f.formatAny(b, v) + } +} + +// generateJSON has the same preference for plain strings as KVFormat. +// In contrast to KVFormat it always produces valid JSON with no line breaks. +func generateJSON(b *bytes.Buffer, v interface{}) { + switch v := v.(type) { + case slog.Value: + switch v.Kind() { + case slog.KindGroup: + // Format as a JSON group. We must not involve f.AnyToStringHook (if there is any), + // because there is no guarantee that it produces valid JSON. + b.WriteByte('{') + for i, attr := range v.Group() { + if i > 0 { + b.WriteByte(',') + } + b.WriteString(strconv.Quote(attr.Key)) + b.WriteByte(':') + generateJSON(b, attr.Value) + } + b.WriteByte('}') + case slog.KindLogValuer: + generateJSON(b, v.Resolve()) + default: + // Peel off the slog.Value wrapper and format the actual value. + generateJSON(b, v.Any()) + } + case fmt.Stringer: + b.WriteString(strconv.Quote(StringerToString(v))) + case logr.Marshaler: + generateJSON(b, MarshalerToValue(v)) + case slog.LogValuer: + generateJSON(b, slog.AnyValue(v).Resolve().Any()) + case string: + b.WriteString(strconv.Quote(v)) + case error: + b.WriteString(strconv.Quote(v.Error())) + default: + formatAsJSON(b, v) + } +} diff --git a/vendor/k8s.io/klog/v2/internal/sloghandler/sloghandler_slog.go b/vendor/k8s.io/klog/v2/internal/sloghandler/sloghandler_slog.go new file mode 100644 index 0000000000..21f1697d09 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/sloghandler/sloghandler_slog.go @@ -0,0 +1,96 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sloghandler + +import ( + "context" + "log/slog" + "runtime" + "strings" + "time" + + "k8s.io/klog/v2/internal/severity" +) + +func Handle(_ context.Context, record slog.Record, groups string, printWithInfos func(file string, line int, now time.Time, err error, s severity.Severity, msg string, kvList []interface{})) error { + now := record.Time + if now.IsZero() { + // This format doesn't support printing entries without a time. + now = time.Now() + } + + // slog has numeric severity levels, with 0 as default "info", negative for debugging, and + // positive with some pre-defined levels for more important. Those ranges get mapped to + // the corresponding klog levels where possible, with "info" the default that is used + // also for negative debug levels. + level := record.Level + s := severity.InfoLog + switch { + case level >= slog.LevelError: + s = severity.ErrorLog + case level >= slog.LevelWarn: + s = severity.WarningLog + } + + var file string + var line int + if record.PC != 0 { + // Same as https://cs.opensource.google/go/x/exp/+/642cacee:slog/record.go;drc=642cacee5cc05231f45555a333d07f1005ffc287;l=70 + fs := runtime.CallersFrames([]uintptr{record.PC}) + f, _ := fs.Next() + if f.File != "" { + file = f.File + if slash := strings.LastIndex(file, "/"); slash >= 0 { + file = file[slash+1:] + } + line = f.Line + } + } else { + file = "???" + line = 1 + } + + kvList := make([]interface{}, 0, 2*record.NumAttrs()) + record.Attrs(func(attr slog.Attr) bool { + kvList = appendAttr(groups, kvList, attr) + return true + }) + + printWithInfos(file, line, now, nil, s, record.Message, kvList) + return nil +} + +func Attrs2KVList(groups string, attrs []slog.Attr) []interface{} { + kvList := make([]interface{}, 0, 2*len(attrs)) + for _, attr := range attrs { + kvList = appendAttr(groups, kvList, attr) + } + return kvList +} + +func appendAttr(groups string, kvList []interface{}, attr slog.Attr) []interface{} { + var key string + if groups != "" { + key = groups + "." + attr.Key + } else { + key = attr.Key + } + return append(kvList, key, attr.Value) +} diff --git a/vendor/k8s.io/klog/v2/k8s_references_slog.go b/vendor/k8s.io/klog/v2/k8s_references_slog.go new file mode 100644 index 0000000000..5522c84c77 --- /dev/null +++ b/vendor/k8s.io/klog/v2/k8s_references_slog.go @@ -0,0 +1,39 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog + +import ( + "log/slog" +) + +func (ref ObjectRef) LogValue() slog.Value { + if ref.Namespace != "" { + return slog.GroupValue(slog.String("name", ref.Name), slog.String("namespace", ref.Namespace)) + } + return slog.GroupValue(slog.String("name", ref.Name)) +} + +var _ slog.LogValuer = ObjectRef{} + +func (ks kobjSlice) LogValue() slog.Value { + return slog.AnyValue(ks.MarshalLog()) +} + +var _ slog.LogValuer = kobjSlice{} diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go index 152f8a6bd6..72502db3ae 100644 --- a/vendor/k8s.io/klog/v2/klog.go +++ b/vendor/k8s.io/klog/v2/klog.go @@ -415,7 +415,7 @@ func init() { logging.stderrThreshold = severityValue{ Severity: severity.ErrorLog, // Default stderrThreshold is ERROR. } - commandLine.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=false)") + commandLine.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=true)") commandLine.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") commandLine.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") @@ -518,9 +518,7 @@ type settings struct { func (s settings) deepCopy() settings { // vmodule is a slice and would be shared, so we have copy it. filter := make([]modulePat, len(s.vmodule.filter)) - for i := range s.vmodule.filter { - filter[i] = s.vmodule.filter[i] - } + copy(filter, s.vmodule.filter) s.vmodule.filter = filter if s.logger != nil { @@ -657,16 +655,15 @@ func (l *loggingT) header(s severity.Severity, depth int) (*buffer.Buffer, strin } } } - return l.formatHeader(s, file, line), file, line + return l.formatHeader(s, file, line, timeNow()), file, line } // formatHeader formats a log header using the provided file name and line number. -func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buffer.Buffer { +func (l *loggingT) formatHeader(s severity.Severity, file string, line int, now time.Time) *buffer.Buffer { buf := buffer.GetBuffer() if l.skipHeaders { return buf } - now := timeNow() buf.FormatHeader(s, file, line, now) return buf } @@ -676,6 +673,10 @@ func (l *loggingT) println(s severity.Severity, logger *logWriter, filter LogFil } func (l *loggingT) printlnDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) { + if false { + _ = fmt.Sprintln(args...) // cause vet to treat this function like fmt.Println + } + buf, file, line := l.header(s, depth) // If a logger is set and doesn't support writing a formatted buffer, // we clear the generated header as we rely on the backing @@ -696,7 +697,15 @@ func (l *loggingT) print(s severity.Severity, logger *logWriter, filter LogFilte } func (l *loggingT) printDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) { + if false { + _ = fmt.Sprint(args...) // // cause vet to treat this function like fmt.Print + } + buf, file, line := l.header(s, depth) + l.printWithInfos(buf, file, line, s, logger, filter, depth+1, args...) +} + +func (l *loggingT) printWithInfos(buf *buffer.Buffer, file string, line int, s severity.Severity, logger *logWriter, filter LogFilter, depth int, args ...interface{}) { // If a logger is set and doesn't support writing a formatted buffer, // we clear the generated header as we rely on the backing // logger implementation to print headers. @@ -719,6 +728,10 @@ func (l *loggingT) printf(s severity.Severity, logger *logWriter, filter LogFilt } func (l *loggingT) printfDepth(s severity.Severity, logger *logWriter, filter LogFilter, depth int, format string, args ...interface{}) { + if false { + _ = fmt.Sprintf(format, args...) // cause vet to treat this function like fmt.Printf + } + buf, file, line := l.header(s, depth) // If a logger is set and doesn't support writing a formatted buffer, // we clear the generated header as we rely on the backing @@ -741,7 +754,7 @@ func (l *loggingT) printfDepth(s severity.Severity, logger *logWriter, filter Lo // alsoLogToStderr is true, the log message always appears on standard error; it // will also appear in the log file unless --logtostderr is set. func (l *loggingT) printWithFileLine(s severity.Severity, logger *logWriter, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { - buf := l.formatHeader(s, file, line) + buf := l.formatHeader(s, file, line, timeNow()) // If a logger is set and doesn't support writing a formatted buffer, // we clear the generated header as we rely on the backing // logger implementation to print headers. @@ -759,7 +772,7 @@ func (l *loggingT) printWithFileLine(s severity.Severity, logger *logWriter, fil l.output(s, logger, buf, 2 /* depth */, file, line, alsoToStderr) } -// if loggr is specified, will call loggr.Error, otherwise output with logging module. +// if logger is specified, will call logger.Error, otherwise output with logging module. func (l *loggingT) errorS(err error, logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) @@ -771,7 +784,7 @@ func (l *loggingT) errorS(err error, logger *logWriter, filter LogFilter, depth l.printS(err, severity.ErrorLog, depth+1, msg, keysAndValues...) } -// if loggr is specified, will call loggr.Info, otherwise output with logging module. +// if logger is specified, will call logger.Info, otherwise output with logging module. func (l *loggingT) infoS(logger *logWriter, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { if filter != nil { msg, keysAndValues = filter.FilterS(msg, keysAndValues) @@ -783,7 +796,7 @@ func (l *loggingT) infoS(logger *logWriter, filter LogFilter, depth int, msg str l.printS(nil, severity.InfoLog, depth+1, msg, keysAndValues...) } -// printS is called from infoS and errorS if loggr is not specified. +// printS is called from infoS and errorS if logger is not specified. // set log severity by s func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, keysAndValues ...interface{}) { // Only create a new buffer if we don't have one cached. @@ -796,7 +809,7 @@ func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, serialize.KVListFormat(&b.Buffer, "err", err) } serialize.KVListFormat(&b.Buffer, keysAndValues...) - l.printDepth(s, logging.logger, nil, depth+1, &b.Buffer) + l.printDepth(s, nil, nil, depth+1, &b.Buffer) // Make the buffer available for reuse. buffer.PutBuffer(b) } @@ -873,6 +886,9 @@ func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Bu if logger.writeKlogBuffer != nil { logger.writeKlogBuffer(data) } else { + if len(data) > 0 && data[len(data)-1] == '\n' { + data = data[:len(data)-1] + } // TODO: set 'severity' and caller information as structured log info // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} if s == severity.ErrorLog { @@ -897,7 +913,7 @@ func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Bu l.exit(err) } } - l.file[severity.InfoLog].Write(data) + _, _ = l.file[severity.InfoLog].Write(data) } else { if l.file[s] == nil { if err := l.createFiles(s); err != nil { @@ -907,20 +923,20 @@ func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Bu } if l.oneOutput { - l.file[s].Write(data) + _, _ = l.file[s].Write(data) } else { switch s { case severity.FatalLog: - l.file[severity.FatalLog].Write(data) + _, _ = l.file[severity.FatalLog].Write(data) fallthrough case severity.ErrorLog: - l.file[severity.ErrorLog].Write(data) + _, _ = l.file[severity.ErrorLog].Write(data) fallthrough case severity.WarningLog: - l.file[severity.WarningLog].Write(data) + _, _ = l.file[severity.WarningLog].Write(data) fallthrough case severity.InfoLog: - l.file[severity.InfoLog].Write(data) + _, _ = l.file[severity.InfoLog].Write(data) } } } @@ -946,7 +962,7 @@ func (l *loggingT) output(s severity.Severity, logger *logWriter, buf *buffer.Bu logExitFunc = func(error) {} // If we get a write error, we'll still exit below. for log := severity.FatalLog; log >= severity.InfoLog; log-- { if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set. - f.Write(trace) + _, _ = f.Write(trace) } } l.mu.Unlock() @@ -1102,7 +1118,7 @@ const flushInterval = 5 * time.Second // flushDaemon periodically flushes the log file buffers. type flushDaemon struct { mu sync.Mutex - clock clock.WithTicker + clock clock.Clock flush func() stopC chan struct{} stopDone chan struct{} @@ -1110,7 +1126,7 @@ type flushDaemon struct { // newFlushDaemon returns a new flushDaemon. If the passed clock is nil, a // clock.RealClock is used. -func newFlushDaemon(flush func(), tickClock clock.WithTicker) *flushDaemon { +func newFlushDaemon(flush func(), tickClock clock.Clock) *flushDaemon { if tickClock == nil { tickClock = clock.RealClock{} } @@ -1201,8 +1217,8 @@ func (l *loggingT) flushAll() { for s := severity.FatalLog; s >= severity.InfoLog; s-- { file := l.file[s] if file != nil { - file.Flush() // ignore error - file.Sync() // ignore error + _ = file.Flush() // ignore error + _ = file.Sync() // ignore error } } if logging.loggerOptions.flush != nil { @@ -1281,9 +1297,7 @@ func (l *loggingT) setV(pc uintptr) Level { fn := runtime.FuncForPC(pc) file, _ := fn.FileLine(pc) // The file is something like /a/b/c/d.go. We want just the d. - if strings.HasSuffix(file, ".go") { - file = file[:len(file)-3] - } + file = strings.TrimSuffix(file, ".go") if slash := strings.LastIndex(file, "/"); slash >= 0 { file = file[slash+1:] } diff --git a/vendor/k8s.io/klog/v2/klog_file.go b/vendor/k8s.io/klog/v2/klog_file.go index 1025d644f3..8bee16204d 100644 --- a/vendor/k8s.io/klog/v2/klog_file.go +++ b/vendor/k8s.io/klog/v2/klog_file.go @@ -109,8 +109,8 @@ func create(tag string, t time.Time, startup bool) (f *os.File, filename string, f, err := openOrCreate(fname, startup) if err == nil { symlink := filepath.Join(dir, link) - os.Remove(symlink) // ignore err - os.Symlink(name, symlink) // ignore err + _ = os.Remove(symlink) // ignore err + _ = os.Symlink(name, symlink) // ignore err return f, fname, nil } lastErr = err diff --git a/vendor/k8s.io/klog/v2/klogr.go b/vendor/k8s.io/klog/v2/klogr.go index 15de00e21f..efec96fd45 100644 --- a/vendor/k8s.io/klog/v2/klogr.go +++ b/vendor/k8s.io/klog/v2/klogr.go @@ -22,6 +22,11 @@ import ( "k8s.io/klog/v2/internal/serialize" ) +const ( + // nameKey is used to log the `WithName` values as an additional attribute. + nameKey = "logger" +) + // NewKlogr returns a logger that is functionally identical to // klogr.NewWithOptions(klogr.FormatKlog), i.e. it passes through to klog. The // difference is that it uses a simpler implementation. @@ -32,10 +37,15 @@ func NewKlogr() Logger { // klogger is a subset of klogr/klogr.go. It had to be copied to break an // import cycle (klogr wants to use klog, and klog wants to use klogr). type klogger struct { - level int callDepth int - prefix string - values []interface{} + + // hasPrefix is true if the first entry in values is the special + // nameKey key/value. Such an entry gets added and later updated in + // WithName. + hasPrefix bool + + values []interface{} + groups string } func (l *klogger) Init(info logr.RuntimeInfo) { @@ -44,34 +54,40 @@ func (l *klogger) Init(info logr.RuntimeInfo) { func (l *klogger) Info(level int, msg string, kvList ...interface{}) { merged := serialize.MergeKVs(l.values, kvList) - if l.prefix != "" { - msg = l.prefix + ": " + msg - } // Skip this function. VDepth(l.callDepth+1, Level(level)).InfoSDepth(l.callDepth+1, msg, merged...) } func (l *klogger) Enabled(level int) bool { - // Skip this function and logr.Logger.Info where Enabled is called. - return VDepth(l.callDepth+2, Level(level)).Enabled() + return VDepth(l.callDepth+1, Level(level)).Enabled() } func (l *klogger) Error(err error, msg string, kvList ...interface{}) { merged := serialize.MergeKVs(l.values, kvList) - if l.prefix != "" { - msg = l.prefix + ": " + msg - } ErrorSDepth(l.callDepth+1, err, msg, merged...) } // WithName returns a new logr.Logger with the specified name appended. klogr -// uses '/' characters to separate name elements. Callers should not pass '/' +// uses '.' characters to separate name elements. Callers should not pass '.' // in the provided name string, but this library does not actually enforce that. func (l klogger) WithName(name string) logr.LogSink { - if len(l.prefix) > 0 { - l.prefix = l.prefix + "/" + if l.hasPrefix { + // Copy slice and modify value. No length checks and type + // assertions are needed because hasPrefix is only true if the + // first two elements exist and are key/value strings. + v := make([]interface{}, 0, len(l.values)) + v = append(v, l.values...) + prefix, _ := v[1].(string) + v[1] = prefix + "." + name + l.values = v + } else { + // Preprend new key/value pair. + v := make([]interface{}, 0, 2+len(l.values)) + v = append(v, nameKey, name) + v = append(v, l.values...) + l.values = v + l.hasPrefix = true } - l.prefix += name return &l } diff --git a/vendor/k8s.io/klog/v2/klogr_slog.go b/vendor/k8s.io/klog/v2/klogr_slog.go new file mode 100644 index 0000000000..f7bf740306 --- /dev/null +++ b/vendor/k8s.io/klog/v2/klogr_slog.go @@ -0,0 +1,96 @@ +//go:build go1.21 +// +build go1.21 + +/* +Copyright 2023 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog + +import ( + "context" + "log/slog" + "strconv" + "time" + + "github.com/go-logr/logr/slogr" + + "k8s.io/klog/v2/internal/buffer" + "k8s.io/klog/v2/internal/serialize" + "k8s.io/klog/v2/internal/severity" + "k8s.io/klog/v2/internal/sloghandler" +) + +func (l *klogger) Handle(ctx context.Context, record slog.Record) error { + if logging.logger != nil { + if slogSink, ok := logging.logger.GetSink().(slogr.SlogSink); ok { + // Let that logger do the work. + return slogSink.Handle(ctx, record) + } + } + + return sloghandler.Handle(ctx, record, l.groups, slogOutput) +} + +// slogOutput corresponds to several different functions in klog.go. +// It goes through some of the same checks and formatting steps before +// it ultimately converges by calling logging.printWithInfos. +func slogOutput(file string, line int, now time.Time, err error, s severity.Severity, msg string, kvList []interface{}) { + // See infoS. + if logging.logger != nil { + // Taking this path happens when klog has a logger installed + // as backend which doesn't support slog. Not good, we have to + // guess about the call depth and drop the actual location. + logger := logging.logger.WithCallDepth(2) + if s > severity.ErrorLog { + logger.Error(err, msg, kvList...) + } else { + logger.Info(msg, kvList...) + } + return + } + + // See printS. + b := buffer.GetBuffer() + b.WriteString(strconv.Quote(msg)) + if err != nil { + serialize.KVListFormat(&b.Buffer, "err", err) + } + serialize.KVListFormat(&b.Buffer, kvList...) + + // See print + header. + buf := logging.formatHeader(s, file, line, now) + logging.printWithInfos(buf, file, line, s, nil, nil, 0, &b.Buffer) + + buffer.PutBuffer(b) +} + +func (l *klogger) WithAttrs(attrs []slog.Attr) slogr.SlogSink { + clone := *l + clone.values = serialize.WithValues(l.values, sloghandler.Attrs2KVList(l.groups, attrs)) + return &clone +} + +func (l *klogger) WithGroup(name string) slogr.SlogSink { + clone := *l + if clone.groups != "" { + clone.groups += "." + name + } else { + clone.groups = name + } + return &clone +} + +var _ slogr.SlogSink = &klogger{} diff --git a/vendor/modules.txt b/vendor/modules.txt index bf867ae0c4..b04bd79550 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -82,13 +82,18 @@ github.com/gammazero/workerpool # github.com/go-co-op/gocron v1.18.0 ## explicit; go 1.19 github.com/go-co-op/gocron -# github.com/go-logr/logr v1.2.4 -## explicit; go 1.16 +# github.com/go-logr/logr v1.3.0 +## explicit; go 1.18 github.com/go-logr/logr github.com/go-logr/logr/funcr +github.com/go-logr/logr/slogr # github.com/go-logr/stdr v1.2.2 ## explicit; go 1.16 github.com/go-logr/stdr +# github.com/go-ole/go-ole v1.2.6 +## explicit; go 1.12 +github.com/go-ole/go-ole +github.com/go-ole/go-ole/oleutil # github.com/go-openapi/jsonpointer v0.19.6 ## explicit; go 1.13 github.com/go-openapi/jsonpointer @@ -111,7 +116,6 @@ github.com/golang/groupcache/lru # github.com/golang/protobuf v1.5.4 ## explicit; go 1.17 github.com/golang/protobuf/descriptor -github.com/golang/protobuf/jsonpb github.com/golang/protobuf/proto github.com/golang/protobuf/protoc-gen-go/descriptor github.com/golang/protobuf/ptypes @@ -228,7 +232,18 @@ github.com/longhorn/backupstore/logging github.com/longhorn/backupstore/systembackup github.com/longhorn/backupstore/types github.com/longhorn/backupstore/util -# github.com/longhorn/go-iscsi-helper v0.0.0-20231113050545-9df1e6b605c7 +# github.com/longhorn/go-common-libs v0.0.0-20240319112414-b75404dc7fbc +## explicit; go 1.21 +github.com/longhorn/go-common-libs/exec +github.com/longhorn/go-common-libs/io +github.com/longhorn/go-common-libs/ns +github.com/longhorn/go-common-libs/proc +github.com/longhorn/go-common-libs/sync +github.com/longhorn/go-common-libs/sys +github.com/longhorn/go-common-libs/test/fake +github.com/longhorn/go-common-libs/types +github.com/longhorn/go-common-libs/utils +# github.com/longhorn/go-iscsi-helper v0.0.0-20240308033847-bc3aab599425 ## explicit; go 1.21 github.com/longhorn/go-iscsi-helper/iscsi github.com/longhorn/go-iscsi-helper/types @@ -236,14 +251,14 @@ github.com/longhorn/go-iscsi-helper/util # github.com/longhorn/go-spdk-helper v0.0.0-20231113055029-9acddd184246 ## explicit; go 1.21 github.com/longhorn/go-spdk-helper/pkg/types -# github.com/longhorn/longhorn-engine v1.5.4 +# github.com/longhorn/longhorn-engine v1.5.5-0.20240319113652-9cdc0f5750a7 ## explicit; go 1.21 github.com/longhorn/longhorn-engine/pkg/meta github.com/longhorn/longhorn-engine/pkg/replica/client github.com/longhorn/longhorn-engine/pkg/types github.com/longhorn/longhorn-engine/pkg/util github.com/longhorn/longhorn-engine/proto/ptypes -# github.com/longhorn/longhorn-instance-manager v1.5.4 +# github.com/longhorn/longhorn-instance-manager v1.5.5-0.20240326065406-8d925c0e7e1e ## explicit; go 1.21 github.com/longhorn/longhorn-instance-manager/pkg/api github.com/longhorn/longhorn-instance-manager/pkg/client @@ -251,7 +266,7 @@ github.com/longhorn/longhorn-instance-manager/pkg/imrpc github.com/longhorn/longhorn-instance-manager/pkg/meta github.com/longhorn/longhorn-instance-manager/pkg/types github.com/longhorn/longhorn-instance-manager/pkg/util -# github.com/longhorn/longhorn-share-manager v1.5.4 +# github.com/longhorn/longhorn-share-manager v1.5.5-0.20240319114127-58303a9ff61f ## explicit; go 1.21 github.com/longhorn/longhorn-share-manager/pkg/client github.com/longhorn/longhorn-share-manager/pkg/crypto @@ -318,6 +333,9 @@ github.com/pkg/errors # github.com/pmezard/go-difflib v1.0.0 ## explicit github.com/pmezard/go-difflib/difflib +# github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c +## explicit; go 1.14 +github.com/power-devops/perfstat # github.com/prometheus/client_golang v1.16.0 ## explicit; go 1.17 github.com/prometheus/client_golang/prometheus @@ -409,6 +427,11 @@ github.com/rogpeppe/go-internal/fmtsort # github.com/russross/blackfriday/v2 v2.1.0 ## explicit github.com/russross/blackfriday/v2 +# github.com/shirou/gopsutil/v3 v3.24.2 +## explicit; go 1.15 +github.com/shirou/gopsutil/v3/common +github.com/shirou/gopsutil/v3/disk +github.com/shirou/gopsutil/v3/internal/common # github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13 github.com/sirupsen/logrus @@ -434,6 +457,9 @@ github.com/stretchr/testify/require # github.com/urfave/cli v1.22.14 ## explicit; go 1.11 github.com/urfave/cli +# github.com/yusufpapurcu/wmi v1.2.4 +## explicit; go 1.16 +github.com/yusufpapurcu/wmi # go.etcd.io/etcd/api/v3 v3.5.9 ## explicit; go 1.19 go.etcd.io/etcd/api/v3/authpb @@ -560,16 +586,16 @@ golang.org/x/net/internal/timeseries golang.org/x/net/proxy golang.org/x/net/trace golang.org/x/net/websocket -# golang.org/x/oauth2 v0.14.0 +# golang.org/x/oauth2 v0.16.0 ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sync v0.5.0 +# golang.org/x/sync v0.6.0 ## explicit; go 1.18 golang.org/x/sync/errgroup golang.org/x/sync/semaphore golang.org/x/sync/singleflight -# golang.org/x/sys v0.16.0 +# golang.org/x/sys v0.18.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/execabs @@ -630,11 +656,11 @@ google.golang.org/appengine/internal/log google.golang.org/appengine/internal/remote_api google.golang.org/appengine/internal/urlfetch google.golang.org/appengine/urlfetch -# google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac +# google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 ## explicit; go 1.19 google.golang.org/genproto/internal google.golang.org/genproto/protobuf/field_mask -# google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 +# google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 ## explicit; go 1.19 google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api/annotations @@ -644,7 +670,7 @@ google.golang.org/genproto/googleapis/api/httpbody ## explicit; go 1.19 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.61.0 +# google.golang.org/grpc v1.62.1 ## explicit; go 1.19 google.golang.org/grpc google.golang.org/grpc/attributes @@ -726,6 +752,7 @@ google.golang.org/protobuf/internal/set google.golang.org/protobuf/internal/strs google.golang.org/protobuf/internal/version google.golang.org/protobuf/proto +google.golang.org/protobuf/protoadapt google.golang.org/protobuf/reflect/protodesc google.golang.org/protobuf/reflect/protoreflect google.golang.org/protobuf/reflect/protoregistry @@ -1408,7 +1435,7 @@ k8s.io/controller-manager/pkg/leadermigration/options # k8s.io/klog v1.0.0 ## explicit; go 1.12 k8s.io/klog -# k8s.io/klog/v2 v2.100.1 +# k8s.io/klog/v2 v2.110.1 ## explicit; go 1.13 k8s.io/klog/v2 k8s.io/klog/v2/internal/buffer @@ -1416,6 +1443,7 @@ k8s.io/klog/v2/internal/clock k8s.io/klog/v2/internal/dbg k8s.io/klog/v2/internal/serialize k8s.io/klog/v2/internal/severity +k8s.io/klog/v2/internal/sloghandler # k8s.io/kms v0.28.2 => k8s.io/kms v0.28.2 ## explicit; go 1.20 k8s.io/kms/apis/v1beta1 @@ -1483,7 +1511,7 @@ k8s.io/metrics/pkg/client/clientset/versioned k8s.io/metrics/pkg/client/clientset/versioned/scheme k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1alpha1 k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1 -# k8s.io/mount-utils v0.28.2 => k8s.io/mount-utils v0.28.2 +# k8s.io/mount-utils v0.29.3 => k8s.io/mount-utils v0.28.2 ## explicit; go 1.20 k8s.io/mount-utils # k8s.io/utils v0.0.0-20240310230437-4693a0247e57