Bump github.com/containers/storage from 1.42.0 to 1.43.0

Bumps [github.com/containers/storage](https://github.com/containers/storage) from 1.42.0 to 1.43.0.
- [Release notes](https://github.com/containers/storage/releases)
- [Changelog](https://github.com/containers/storage/blob/main/docs/containers-storage-changes.md)
- [Commits](https://github.com/containers/storage/compare/v1.42.0...v1.43.0)

---
updated-dependencies:
- dependency-name: github.com/containers/storage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot] 2022-09-29 08:12:13 +00:00 committed by GitHub
parent cf354b7abd
commit feabfac2a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
110 changed files with 1478 additions and 749 deletions

10
go.mod
View File

@ -6,7 +6,7 @@ require (
github.com/containers/common v0.49.1
github.com/containers/image/v5 v5.22.1-0.20220823195718-d2de3afd63b9
github.com/containers/ocicrypt v1.1.5
github.com/containers/storage v1.42.0
github.com/containers/storage v1.43.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.3-0.20220114050600-8b9d41f48198
github.com/opencontainers/image-tools v1.0.0-rc3
@ -23,7 +23,7 @@ require (
require (
github.com/BurntSushi/toml v1.2.0 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/hcsshim v0.9.3 // indirect
github.com/Microsoft/hcsshim v0.9.4 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
github.com/beorn7/perks v1.0.1 // indirect
@ -38,7 +38,7 @@ require (
github.com/docker/docker-credential-helpers v0.6.4 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@ -63,11 +63,11 @@ require (
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect
github.com/mistifyio/go-zfs/v3 v3.0.0 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/opencontainers/runc v1.1.3 // indirect
github.com/opencontainers/runc v1.1.4 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect
github.com/opencontainers/selinux v1.10.1 // indirect
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect

14
go.sum
View File

@ -143,8 +143,9 @@ github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwT
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.9.3 h1:k371PzBuRrz2b+ebGuI2nVgVhgsVX60jMfSw80NECxo=
github.com/Microsoft/hcsshim v0.9.3/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.9.4 h1:mnUj0ivWy6UzbB1uLFqKR6F+ZyiDc7j4iGgHTpO+5+I=
github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@ -409,8 +410,9 @@ github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B
github.com/containers/ocicrypt v1.1.3/go.mod h1:xpdkbVAuaH3WzbEabUd5yDsl9SwJA5pABH85425Es2g=
github.com/containers/ocicrypt v1.1.5 h1:UO+gBnBXvMvC7HTXLh0bPgLslfW8HlY+oxYcoSHBcZQ=
github.com/containers/ocicrypt v1.1.5/go.mod h1:WgjxPWdTJMqYMjf3M6cuIFFA1/MpyyhIM99YInA+Rvc=
github.com/containers/storage v1.42.0 h1:zm2AQD4NDeTB3JQ8X+Wo5+VRqNB+b4ocEd7Qj6ylPJA=
github.com/containers/storage v1.42.0/go.mod h1:JiUJwOgOo1dr2DdOUc1MRe2GCAXABYoYmOdPF8yvH78=
github.com/containers/storage v1.43.0 h1:P+zulGXA3mqe2GnYmZU0xu87Wy1M0PVHM2ucrgmvTdU=
github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@ -484,8 +486,9 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6Uezg
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
@ -1185,6 +1188,8 @@ github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mistifyio/go-zfs/v3 v3.0.0 h1:J5QK618xRcXnQYZ2GE5FdmpS1ufIrWue+lR/mpe6/14=
github.com/mistifyio/go-zfs/v3 v3.0.0/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
@ -1319,8 +1324,9 @@ github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w=
github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg=
github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=

View File

@ -57,7 +57,7 @@ func pollIOCP(ctx context.Context, iocpHandle windows.Handle) {
}).Warn("failed to parse job object message")
continue
}
if err := msq.Write(notification); err == queue.ErrQueueClosed {
if err := msq.Enqueue(notification); err == queue.ErrQueueClosed {
// Write will only return an error when the queue is closed.
// The only time a queue would ever be closed is when we call `Close` on
// the job it belongs to which also removes it from the jobMap, so something

View File

@ -68,6 +68,9 @@ type Options struct {
// `UseNTVariant` specifies if we should use the `Nt` variant of Open/CreateJobObject.
// Defaults to false.
UseNTVariant bool
// `IOTracking` enables tracking I/O statistics on the job object. More specifically this
// calls SetInformationJobObject with the JobObjectIoAttribution class.
EnableIOTracking bool
}
// Create creates a job object.
@ -134,6 +137,12 @@ func Create(ctx context.Context, options *Options) (_ *JobObject, err error) {
job.mq = mq
}
if options.EnableIOTracking {
if err := enableIOTracking(jobHandle); err != nil {
return nil, err
}
}
return job, nil
}
@ -235,7 +244,7 @@ func (job *JobObject) PollNotification() (interface{}, error) {
if job.mq == nil {
return nil, ErrNotRegistered
}
return job.mq.ReadOrWait()
return job.mq.Dequeue()
}
// UpdateProcThreadAttribute updates the passed in ProcThreadAttributeList to contain what is necessary to
@ -330,7 +339,7 @@ func (job *JobObject) Pids() ([]uint32, error) {
err := winapi.QueryInformationJobObject(
job.handle,
winapi.JobObjectBasicProcessIdList,
uintptr(unsafe.Pointer(&info)),
unsafe.Pointer(&info),
uint32(unsafe.Sizeof(info)),
nil,
)
@ -356,7 +365,7 @@ func (job *JobObject) Pids() ([]uint32, error) {
if err = winapi.QueryInformationJobObject(
job.handle,
winapi.JobObjectBasicProcessIdList,
uintptr(unsafe.Pointer(&buf[0])),
unsafe.Pointer(&buf[0]),
uint32(len(buf)),
nil,
); err != nil {
@ -384,7 +393,7 @@ func (job *JobObject) QueryMemoryStats() (*winapi.JOBOBJECT_MEMORY_USAGE_INFORMA
if err := winapi.QueryInformationJobObject(
job.handle,
winapi.JobObjectMemoryUsageInformation,
uintptr(unsafe.Pointer(&info)),
unsafe.Pointer(&info),
uint32(unsafe.Sizeof(info)),
nil,
); err != nil {
@ -406,7 +415,7 @@ func (job *JobObject) QueryProcessorStats() (*winapi.JOBOBJECT_BASIC_ACCOUNTING_
if err := winapi.QueryInformationJobObject(
job.handle,
winapi.JobObjectBasicAccountingInformation,
uintptr(unsafe.Pointer(&info)),
unsafe.Pointer(&info),
uint32(unsafe.Sizeof(info)),
nil,
); err != nil {
@ -415,7 +424,9 @@ func (job *JobObject) QueryProcessorStats() (*winapi.JOBOBJECT_BASIC_ACCOUNTING_
return &info, nil
}
// QueryStorageStats gets the storage (I/O) stats for the job object.
// QueryStorageStats gets the storage (I/O) stats for the job object. This call will error
// if either `EnableIOTracking` wasn't set to true on creation of the job, or SetIOTracking()
// hasn't been called since creation of the job.
func (job *JobObject) QueryStorageStats() (*winapi.JOBOBJECT_IO_ATTRIBUTION_INFORMATION, error) {
job.handleLock.RLock()
defer job.handleLock.RUnlock()
@ -430,7 +441,7 @@ func (job *JobObject) QueryStorageStats() (*winapi.JOBOBJECT_IO_ATTRIBUTION_INFO
if err := winapi.QueryInformationJobObject(
job.handle,
winapi.JobObjectIoAttribution,
uintptr(unsafe.Pointer(&info)),
unsafe.Pointer(&info),
uint32(unsafe.Sizeof(info)),
nil,
); err != nil {
@ -476,7 +487,7 @@ func (job *JobObject) QueryPrivateWorkingSet() (uint64, error) {
status := winapi.NtQueryInformationProcess(
h,
winapi.ProcessVmCounters,
uintptr(unsafe.Pointer(&vmCounters)),
unsafe.Pointer(&vmCounters),
uint32(unsafe.Sizeof(vmCounters)),
nil,
)
@ -497,3 +508,31 @@ func (job *JobObject) QueryPrivateWorkingSet() (uint64, error) {
return jobWorkingSetSize, nil
}
// SetIOTracking enables IO tracking for processes in the job object.
// This enables use of the QueryStorageStats method.
func (job *JobObject) SetIOTracking() error {
job.handleLock.RLock()
defer job.handleLock.RUnlock()
if job.handle == 0 {
return ErrAlreadyClosed
}
return enableIOTracking(job.handle)
}
func enableIOTracking(job windows.Handle) error {
info := winapi.JOBOBJECT_IO_ATTRIBUTION_INFORMATION{
ControlFlags: winapi.JOBOBJECT_IO_ATTRIBUTION_CONTROL_ENABLE,
}
if _, err := windows.SetInformationJobObject(
job,
winapi.JobObjectIoAttribution,
uintptr(unsafe.Pointer(&info)),
uint32(unsafe.Sizeof(info)),
); err != nil {
return fmt.Errorf("failed to enable IO tracking on job object: %w", err)
}
return nil
}

View File

@ -202,7 +202,7 @@ func (job *JobObject) getExtendedInformation() (*windows.JOBOBJECT_EXTENDED_LIMI
if err := winapi.QueryInformationJobObject(
job.handle,
windows.JobObjectExtendedLimitInformation,
uintptr(unsafe.Pointer(&info)),
unsafe.Pointer(&info),
uint32(unsafe.Sizeof(info)),
nil,
); err != nil {
@ -224,7 +224,7 @@ func (job *JobObject) getCPURateControlInformation() (*winapi.JOBOBJECT_CPU_RATE
if err := winapi.QueryInformationJobObject(
job.handle,
windows.JobObjectCpuRateControlInformation,
uintptr(unsafe.Pointer(&info)),
unsafe.Pointer(&info),
uint32(unsafe.Sizeof(info)),
nil,
); err != nil {

View File

@ -5,10 +5,7 @@ import (
"sync"
)
var (
ErrQueueClosed = errors.New("the queue is closed for reading and writing")
ErrQueueEmpty = errors.New("the queue is empty")
)
var ErrQueueClosed = errors.New("the queue is closed for reading and writing")
// MessageQueue represents a threadsafe message queue to be used to retrieve or
// write messages to.
@ -29,8 +26,8 @@ func NewMessageQueue() *MessageQueue {
}
}
// Write writes `msg` to the queue.
func (mq *MessageQueue) Write(msg interface{}) error {
// Enqueue writes `msg` to the queue.
func (mq *MessageQueue) Enqueue(msg interface{}) error {
mq.m.Lock()
defer mq.m.Unlock()
@ -43,55 +40,37 @@ func (mq *MessageQueue) Write(msg interface{}) error {
return nil
}
// Read will read a value from the queue if available, otherwise return an error.
func (mq *MessageQueue) Read() (interface{}, error) {
// Dequeue will read a value from the queue and remove it. If the queue
// is empty, this will block until the queue is closed or a value gets enqueued.
func (mq *MessageQueue) Dequeue() (interface{}, error) {
mq.m.Lock()
defer mq.m.Unlock()
for !mq.closed && mq.size() == 0 {
mq.c.Wait()
}
// We got woken up, check if it's because the queue got closed.
if mq.closed {
return nil, ErrQueueClosed
}
if mq.isEmpty() {
return nil, ErrQueueEmpty
}
val := mq.messages[0]
mq.messages[0] = nil
mq.messages = mq.messages[1:]
return val, nil
}
// ReadOrWait will read a value from the queue if available, else it will wait for a
// value to become available. This will block forever if nothing gets written or until
// the queue gets closed.
func (mq *MessageQueue) ReadOrWait() (interface{}, error) {
mq.m.Lock()
if mq.closed {
mq.m.Unlock()
return nil, ErrQueueClosed
}
if mq.isEmpty() {
for !mq.closed && mq.isEmpty() {
mq.c.Wait()
}
mq.m.Unlock()
return mq.Read()
}
val := mq.messages[0]
mq.messages[0] = nil
mq.messages = mq.messages[1:]
mq.m.Unlock()
return val, nil
}
// IsEmpty returns if the queue is empty
func (mq *MessageQueue) IsEmpty() bool {
// Size returns the size of the queue.
func (mq *MessageQueue) Size() int {
mq.m.RLock()
defer mq.m.RUnlock()
return len(mq.messages) == 0
return mq.size()
}
// Nonexported empty check that doesn't lock so we can call this in Read and Write.
func (mq *MessageQueue) isEmpty() bool {
return len(mq.messages) == 0
// Nonexported size check to check if the queue is empty inside already locked functions.
func (mq *MessageQueue) size() int {
return len(mq.messages)
}
// Close closes the queue for future writes or reads. Any attempts to read or write from the
@ -99,13 +78,15 @@ func (mq *MessageQueue) isEmpty() bool {
func (mq *MessageQueue) Close() {
mq.m.Lock()
defer mq.m.Unlock()
// Already closed
// Already closed, noop
if mq.closed {
return
}
mq.messages = nil
mq.closed = true
// If there's anybody currently waiting on a value from ReadOrWait, we need to
// If there's anybody currently waiting on a value from Dequeue, we need to
// broadcast so the read(s) can return ErrQueueClosed.
mq.c.Broadcast()
}

View File

@ -175,7 +175,7 @@ type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct {
// LPDWORD lpReturnLength
// );
//
//sys QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo uintptr, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) = kernel32.QueryInformationJobObject
//sys QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo unsafe.Pointer, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) = kernel32.QueryInformationJobObject
// HANDLE OpenJobObjectW(
// DWORD dwDesiredAccess,

View File

@ -18,7 +18,7 @@ const ProcessVmCounters = 3
// [out, optional] PULONG ReturnLength
// );
//
//sys NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo uintptr, processInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQueryInformationProcess
//sys NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo unsafe.Pointer, processInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQueryInformationProcess
// typedef struct _VM_COUNTERS_EX
// {

View File

@ -12,7 +12,8 @@ const STATUS_INFO_LENGTH_MISMATCH = 0xC0000004
// ULONG SystemInformationLength,
// PULONG ReturnLength
// );
//sys NtQuerySystemInformation(systemInfoClass int, systemInformation uintptr, systemInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQuerySystemInformation
//
//sys NtQuerySystemInformation(systemInfoClass int, systemInformation unsafe.Pointer, systemInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQuerySystemInformation
type SYSTEM_PROCESS_INFORMATION struct {
NextEntryOffset uint32 // ULONG

View File

@ -100,7 +100,7 @@ func resizePseudoConsole(hPc windows.Handle, size uint32) (hr error) {
return
}
func NtQuerySystemInformation(systemInfoClass int, systemInformation uintptr, systemInfoLength uint32, returnLength *uint32) (status uint32) {
func NtQuerySystemInformation(systemInfoClass int, systemInformation unsafe.Pointer, systemInfoLength uint32, returnLength *uint32) (status uint32) {
r0, _, _ := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInfoClass), uintptr(systemInformation), uintptr(systemInfoLength), uintptr(unsafe.Pointer(returnLength)), 0, 0)
status = uint32(r0)
return
@ -152,7 +152,7 @@ func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result
return
}
func QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo uintptr, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) {
func QueryInformationJobObject(jobHandle windows.Handle, infoClass uint32, jobObjectInfo unsafe.Pointer, jobObjectInformationLength uint32, lpReturnLength *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(jobHandle), uintptr(infoClass), uintptr(jobObjectInfo), uintptr(jobObjectInformationLength), uintptr(unsafe.Pointer(lpReturnLength)), 0)
if r1 == 0 {
if e1 != 0 {
@ -244,7 +244,7 @@ func LocalFree(ptr uintptr) {
return
}
func NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo uintptr, processInfoLength uint32, returnLength *uint32) (status uint32) {
func NtQueryInformationProcess(processHandle windows.Handle, processInfoClass uint32, processInfo unsafe.Pointer, processInfoLength uint32, returnLength *uint32) (status uint32) {
r0, _, _ := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInfoClass), uintptr(processInfo), uintptr(processInfoLength), uintptr(unsafe.Pointer(returnLength)), 0)
status = uint32(r0)
return

View File

@ -132,7 +132,7 @@ lint_task:
meta_task:
container:
image: "quay.io/libpod/imgts:${IMAGE_SUFFIX}"
image: "quay.io/libpod/imgts:latest"
cpu: 1
memory: 1

View File

@ -1 +1 @@
1.42.0
1.43.0

View File

@ -3,7 +3,6 @@ package storage
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
@ -144,26 +143,26 @@ func copyContainer(c *Container) *Container {
}
func (c *Container) MountLabel() string {
if label, ok := c.Flags["MountLabel"].(string); ok {
if label, ok := c.Flags[mountLabelFlag].(string); ok {
return label
}
return ""
}
func (c *Container) ProcessLabel() string {
if label, ok := c.Flags["ProcessLabel"].(string); ok {
if label, ok := c.Flags[processLabelFlag].(string); ok {
return label
}
return ""
}
func (c *Container) MountOpts() []string {
switch c.Flags["MountOpts"].(type) {
switch c.Flags[mountOptsFlag].(type) {
case []string:
return c.Flags["MountOpts"].([]string)
return c.Flags[mountOptsFlag].([]string)
case []interface{}:
var mountOpts []string
for _, v := range c.Flags["MountOpts"].([]interface{}) {
for _, v := range c.Flags[mountOptsFlag].([]interface{}) {
if flag, ok := v.(string); ok {
mountOpts = append(mountOpts, flag)
}
@ -197,7 +196,7 @@ func (r *containerStore) datapath(id, key string) string {
func (r *containerStore) Load() error {
needSave := false
rpath := r.containerspath()
data, err := ioutil.ReadFile(rpath)
data, err := os.ReadFile(rpath)
if err != nil && !os.IsNotExist(err) {
return err
}
@ -321,10 +320,10 @@ func (r *containerStore) Create(id string, names []string, image, layer, metadat
return nil, ErrDuplicateID
}
if options.MountOpts != nil {
options.Flags["MountOpts"] = append([]string{}, options.MountOpts...)
options.Flags[mountOptsFlag] = append([]string{}, options.MountOpts...)
}
if options.Volatile {
options.Flags["Volatile"] = true
options.Flags[volatileFlag] = true
}
names = dedupeNames(names)
for _, name := range names {
@ -484,7 +483,7 @@ func (r *containerStore) BigData(id, key string) ([]byte, error) {
if !ok {
return nil, ErrContainerUnknown
}
return ioutil.ReadFile(r.datapath(c.ID, key))
return os.ReadFile(r.datapath(c.ID, key))
}
func (r *containerStore) BigDataSize(id, key string) (int64, error) {

View File

@ -29,7 +29,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
"path"
@ -47,7 +46,7 @@ import (
mountpk "github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
"github.com/containers/storage/pkg/system"
"github.com/opencontainers/runc/libcontainer/userns"
"github.com/containers/storage/pkg/unshare"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus"
"github.com/vbatts/tar-split/tar/storage"
@ -170,7 +169,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
for _, path := range []string{"mnt", "diff"} {
p := filepath.Join(home, path)
entries, err := ioutil.ReadDir(p)
entries, err := os.ReadDir(p)
if err != nil {
logger.WithError(err).WithField("dir", p).Error("error reading dir entries")
continue
@ -200,7 +199,7 @@ func supportsAufs() error {
// proc/filesystems for when aufs is supported
exec.Command("modprobe", "aufs").Run()
if userns.RunningInUserNS() {
if unshare.IsRootless() {
return ErrAufsNested
}
@ -730,14 +729,14 @@ func (a *Driver) aufsMount(ro []string, rw, target string, options graphdriver.M
// version of aufs.
func useDirperm() bool {
enableDirpermLock.Do(func() {
base, err := ioutil.TempDir("", "storage-aufs-base")
base, err := os.MkdirTemp("", "storage-aufs-base")
if err != nil {
logrus.Errorf("Checking dirperm1: %v", err)
return
}
defer os.RemoveAll(base)
union, err := ioutil.TempDir("", "storage-aufs-union")
union, err := os.MkdirTemp("", "storage-aufs-union")
if err != nil {
logrus.Errorf("Checking dirperm1: %v", err)
return

View File

@ -1,17 +1,17 @@
//go:build linux
// +build linux
package aufs
import (
"bufio"
"io/ioutil"
"os"
"path"
)
// Return all the directories
func loadIds(root string) ([]string, error) {
dirs, err := ioutil.ReadDir(root)
dirs, err := os.ReadDir(root)
if err != nil {
return nil, err
}

View File

@ -1,12 +0,0 @@
// +build !linux
package aufs
import "errors"
// MsRemount declared to specify a non-linux system mount.
const MsRemount = 0
func mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
return errors.New("mount is not implemented on this platform")
}

View File

@ -18,7 +18,6 @@ import "C"
import (
"fmt"
"io/fs"
"io/ioutil"
"math"
"os"
"path"
@ -524,7 +523,7 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
if err := idtools.MkdirAllAs(quotas, 0700, rootUID, rootGID); err != nil {
return err
}
if err := ioutil.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0644); err != nil {
if err := os.WriteFile(path.Join(quotas, id), []byte(fmt.Sprint(driver.options.size)), 0644); err != nil {
return err
}
}
@ -643,7 +642,7 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) {
return "", fmt.Errorf("%s: not a directory", dir)
}
if quota, err := ioutil.ReadFile(d.quotasDirID(id)); err == nil {
if quota, err := os.ReadFile(d.quotasDirID(id)); err == nil {
if size, err := strconv.ParseUint(string(quota), 10, 64); err == nil && size >= d.options.minSpace {
if err := d.enableQuota(); err != nil {
return "", err

View File

@ -1,4 +1,5 @@
// +build !linux btrfs_noversion !cgo
//go:build linux && btrfs_noversion && cgo
// +build linux,btrfs_noversion,cgo
package btrfs

View File

@ -2,6 +2,7 @@ package graphdriver
import (
"bytes"
"errors"
"fmt"
"os"
@ -93,7 +94,7 @@ func ChownPathByMaps(path string, toContainer, toHost *idtools.IDMappings) error
return err
}
if len(output) > 0 {
return fmt.Errorf(string(output))
return errors.New(string(output))
}
return nil

View File

@ -27,7 +27,6 @@ import (
"github.com/containers/storage/pkg/pools"
"github.com/containers/storage/pkg/system"
"github.com/containers/storage/pkg/unshare"
"github.com/opencontainers/runc/libcontainer/userns"
"golang.org/x/sys/unix"
)
@ -207,7 +206,7 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
s.Close()
case mode&os.ModeDevice != 0:
if userns.RunningInUserNS() {
if unshare.IsRootless() {
// cannot create a device if running in user namespace
return nil
}

View File

@ -8,7 +8,6 @@ import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@ -154,7 +153,7 @@ func readLVMConfig(root string) (directLVMConfig, error) {
var cfg directLVMConfig
p := filepath.Join(root, "setup-config.json")
b, err := ioutil.ReadFile(p)
b, err := os.ReadFile(p)
if err != nil {
if os.IsNotExist(err) {
return cfg, nil
@ -166,9 +165,10 @@ func readLVMConfig(root string) (directLVMConfig, error) {
if len(b) == 0 {
return cfg, nil
}
err = json.Unmarshal(b, &cfg)
return cfg, fmt.Errorf("unmarshaling previous device setup config: %w", err)
if err := json.Unmarshal(b, &cfg); err != nil {
return cfg, fmt.Errorf("unmarshaling previous device setup config: %w", err)
}
return cfg, nil
}
func writeLVMConfig(root string, cfg directLVMConfig) error {
@ -177,7 +177,7 @@ func writeLVMConfig(root string, cfg directLVMConfig) error {
if err != nil {
return fmt.Errorf("marshalling direct lvm config: %w", err)
}
if err := ioutil.WriteFile(p, b, 0600); err != nil {
if err := os.WriteFile(p, b, 0600); err != nil {
return fmt.Errorf("writing direct lvm config to file: %w", err)
}
return nil
@ -241,7 +241,7 @@ func setupDirectLVM(cfg directLVMConfig) error {
}
profile := fmt.Sprintf("activation{\nthin_pool_autoextend_threshold=%d\nthin_pool_autoextend_percent=%d\n}", cfg.AutoExtendThreshold, cfg.AutoExtendPercent)
err = ioutil.WriteFile(lvmProfileDir+"/storage-thinpool.profile", []byte(profile), 0600)
err = os.WriteFile(lvmProfileDir+"/storage-thinpool.profile", []byte(profile), 0600)
if err != nil {
return fmt.Errorf("writing storage thinp autoextend profile: %w", err)
}

View File

@ -9,7 +9,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
"path"
@ -331,7 +330,7 @@ func (devices *DeviceSet) removeMetadata(info *devInfo) error {
// Given json data and file path, write it to disk
func (devices *DeviceSet) writeMetaFile(jsonData []byte, filePath string) error {
tmpFile, err := ioutil.TempFile(devices.metadataDir(), ".tmp")
tmpFile, err := os.CreateTemp(devices.metadataDir(), ".tmp")
if err != nil {
return fmt.Errorf("devmapper: Error creating metadata file: %s", err)
}
@ -630,7 +629,7 @@ func (devices *DeviceSet) createFilesystem(info *devInfo) (err error) {
func (devices *DeviceSet) migrateOldMetaData() error {
// Migrate old metadata file
jsonData, err := ioutil.ReadFile(devices.oldMetadataFile())
jsonData, err := os.ReadFile(devices.oldMetadataFile())
if err != nil && !os.IsNotExist(err) {
return err
}
@ -955,7 +954,7 @@ func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *devInf
func (devices *DeviceSet) loadMetadata(hash string) *devInfo {
info := &devInfo{Hash: hash, devices: devices}
jsonData, err := ioutil.ReadFile(devices.metadataFile(info))
jsonData, err := os.ReadFile(devices.metadataFile(info))
if err != nil {
logrus.Debugf("devmapper: Failed to read %s with err: %v", devices.metadataFile(info), err)
return nil
@ -1276,11 +1275,11 @@ func (devices *DeviceSet) setupBaseImage() error {
}
func setCloseOnExec(name string) {
fileInfos, _ := ioutil.ReadDir("/proc/self/fd")
for _, i := range fileInfos {
link, _ := os.Readlink(filepath.Join("/proc/self/fd", i.Name()))
fileEntries, _ := os.ReadDir("/proc/self/fd")
for _, e := range fileEntries {
link, _ := os.Readlink(filepath.Join("/proc/self/fd", e.Name()))
if link == name {
fd, err := strconv.Atoi(i.Name())
fd, err := strconv.Atoi(e.Name())
if err == nil {
unix.CloseOnExec(fd)
}
@ -1370,7 +1369,7 @@ func (devices *DeviceSet) ResizePool(size int64) error {
}
func (devices *DeviceSet) loadTransactionMetaData() error {
jsonData, err := ioutil.ReadFile(devices.transactionMetaFile())
jsonData, err := os.ReadFile(devices.transactionMetaFile())
if err != nil {
// There is no active transaction. This will be the case
// during upgrade.
@ -1451,7 +1450,7 @@ func (devices *DeviceSet) processPendingTransaction() error {
}
func (devices *DeviceSet) loadDeviceSetMetaData() error {
jsonData, err := ioutil.ReadFile(devices.deviceSetMetaFile())
jsonData, err := os.ReadFile(devices.deviceSetMetaFile())
if err != nil {
// For backward compatibility return success if file does
// not exist.
@ -2258,7 +2257,7 @@ func (devices *DeviceSet) cancelDeferredRemoval(info *devInfo) error {
}
func (devices *DeviceSet) unmountAndDeactivateAll(dir string) {
files, err := ioutil.ReadDir(dir)
files, err := os.ReadDir(dir)
if err != nil {
logrus.Warnf("devmapper: unmountAndDeactivate: %s", err)
return

View File

@ -1,10 +1,10 @@
//go:build linux && cgo
// +build linux,cgo
package devmapper
import (
"fmt"
"io/ioutil"
"os"
"path"
"strconv"
@ -227,7 +227,7 @@ func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) {
if _, err := os.Stat(idFile); err != nil && os.IsNotExist(err) {
// Create an "id" file with the container/image id in it to help reconstruct this in case
// of later problems
if err := ioutil.WriteFile(idFile, []byte(id), 0600); err != nil {
if err := os.WriteFile(idFile, []byte(id), 0600); err != nil {
d.ctr.Decrement(mp)
d.DeviceSet.UnmountDevice(id, mp)
return "", err

View File

@ -1,3 +1,6 @@
//go:build linux && cgo
// +build linux,cgo
package devmapper
import jsoniter "github.com/json-iterator/go"

View File

@ -48,7 +48,7 @@ type CreateOpts struct {
ignoreChownErrors bool
}
// MountOpts contains optional arguments for LayerStope.Mount() methods.
// MountOpts contains optional arguments for Driver.Get() methods.
type MountOpts struct {
// Mount label is the MAC Labels to assign to mount point (SELINUX)
MountLabel string

View File

@ -7,6 +7,7 @@ import (
"path/filepath"
"github.com/containers/storage/pkg/mount"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@ -127,9 +128,14 @@ var (
// GetFSMagic returns the filesystem id given the path.
func GetFSMagic(rootpath string) (FsMagic, error) {
var buf unix.Statfs_t
if err := unix.Statfs(filepath.Dir(rootpath), &buf); err != nil {
path := filepath.Dir(rootpath)
if err := unix.Statfs(path, &buf); err != nil {
return 0, err
}
if _, ok := FsNames[FsMagic(buf.Type)]; !ok {
logrus.Debugf("Unknown filesystem type %#x reported for %s", buf.Type, path)
}
return FsMagic(buf.Type), nil
}

View File

@ -10,7 +10,7 @@ import (
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/ioutils"
"github.com/opencontainers/runc/libcontainer/userns"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
)
@ -33,10 +33,11 @@ type NaiveDiffDriver struct {
// NewNaiveDiffDriver returns a fully functional driver that wraps the
// given ProtoDriver and adds the capability of the following methods which
// it may or may not support on its own:
// Diff(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (io.ReadCloser, error)
// Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) ([]archive.Change, error)
// ApplyDiff(id, parent string, options ApplyDiffOpts) (size int64, err error)
// DiffSize(id string, idMappings *idtools.IDMappings, parent, parentMappings *idtools.IDMappings, mountLabel string) (size int64, err error)
//
// Diff(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) (io.ReadCloser, error)
// Changes(id string, idMappings *idtools.IDMappings, parent string, parentMappings *idtools.IDMappings, mountLabel string) ([]archive.Change, error)
// ApplyDiff(id, parent string, options ApplyDiffOpts) (size int64, err error)
// DiffSize(id string, idMappings *idtools.IDMappings, parent, parentMappings *idtools.IDMappings, mountLabel string) (size int64, err error)
func NewNaiveDiffDriver(driver ProtoDriver, updater LayerIDMapUpdater) Driver {
return &NaiveDiffDriver{ProtoDriver: driver, LayerIDMapUpdater: updater}
}
@ -109,7 +110,7 @@ func (gdw *NaiveDiffDriver) Diff(id string, idMappings *idtools.IDMappings, pare
// are extracted from tar's with full second precision on modified time.
// We need this hack here to make sure calls within same second receive
// correct result.
time.Sleep(startTime.Truncate(time.Second).Add(time.Second).Sub(time.Now()))
time.Sleep(time.Until(startTime.Truncate(time.Second).Add(time.Second)))
return err
}), nil
}
@ -179,7 +180,7 @@ func (gdw *NaiveDiffDriver) ApplyDiff(id, parent string, options ApplyDiffOpts)
}
tarOptions := &archive.TarOptions{
InUserNS: userns.RunningInUserNS(),
InUserNS: unshare.IsRootless(),
IgnoreChownErrors: options.IgnoreChownErrors,
ForceMask: forceMask,
}

View File

@ -6,7 +6,6 @@ package overlay
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
@ -27,7 +26,7 @@ import (
// directory or the kernel enable CONFIG_OVERLAY_FS_REDIRECT_DIR.
// When these exist naive diff should be used.
func doesSupportNativeDiff(d, mountOpts string) error {
td, err := ioutil.TempDir(d, "opaque-bug-check")
td, err := os.MkdirTemp(d, "opaque-bug-check")
if err != nil {
return err
}
@ -82,7 +81,7 @@ func doesSupportNativeDiff(d, mountOpts string) error {
}()
// Touch file in d to force copy up of opaque directory "d" from "l2" to "l3"
if err := ioutil.WriteFile(filepath.Join(td, "merged", "d", "f"), []byte{}, 0644); err != nil {
if err := os.WriteFile(filepath.Join(td, "merged", "d", "f"), []byte{}, 0644); err != nil {
return fmt.Errorf("failed to write to merged directory: %w", err)
}
@ -121,7 +120,7 @@ func doesSupportNativeDiff(d, mountOpts string) error {
// copying up a file from a lower layer unless/until its contents are being
// modified
func doesMetacopy(d, mountOpts string) (bool, error) {
td, err := ioutil.TempDir(d, "metacopy-check")
td, err := os.MkdirTemp(d, "metacopy-check")
if err != nil {
return false, err
}
@ -158,7 +157,7 @@ func doesMetacopy(d, mountOpts string) (bool, error) {
}
if err := unix.Mount("overlay", filepath.Join(td, "merged"), "overlay", uintptr(flags), opts); err != nil {
if errors.Is(err, unix.EINVAL) {
logrus.Info("metacopy option not supported on this kernel", mountOpts)
logrus.Infof("overlay: metacopy option not supported on this kernel, checked using options %q", mountOpts)
return false, nil
}
return false, fmt.Errorf("failed to mount overlay for metacopy check with %q options: %w", mountOpts, err)
@ -186,7 +185,7 @@ func doesMetacopy(d, mountOpts string) (bool, error) {
// doesVolatile checks if the filesystem supports the "volatile" mount option
func doesVolatile(d string) (bool, error) {
td, err := ioutil.TempDir(d, "volatile-check")
td, err := os.MkdirTemp(d, "volatile-check")
if err != nil {
return false, err
}
@ -224,7 +223,7 @@ func doesVolatile(d string) (bool, error) {
// supportsIdmappedLowerLayers checks if the kernel supports mounting overlay on top of
// a idmapped lower layer.
func supportsIdmappedLowerLayers(home string) (bool, error) {
layerDir, err := ioutil.TempDir(home, "compat")
layerDir, err := os.MkdirTemp(home, "compat")
if err != nil {
return false, err
}

View File

@ -1,14 +1,17 @@
// +build go1.16
//go:build linux
// +build linux
package overlay
import (
"errors"
"io/fs"
"path/filepath"
"strings"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/system"
"golang.org/x/sys/unix"
)
func scanForMountProgramIndicators(home string) (detected bool, err error) {
@ -26,7 +29,7 @@ func scanForMountProgramIndicators(home string) (detected bool, err error) {
}
if d.IsDir() {
xattrs, err := system.Llistxattr(path)
if err != nil {
if err != nil && !errors.Is(err, unix.EOPNOTSUPP) {
return err
}
for _, xattr := range xattrs {

View File

@ -5,7 +5,6 @@ package overlay
import (
"fmt"
"io/ioutil"
"os"
"syscall"
"unsafe"
@ -21,17 +20,6 @@ type attr struct {
userNs uint64
}
const (
// _MOUNT_ATTR_IDMAP - Idmap mount to @userns_fd in struct mount_attr
_MOUNT_ATTR_IDMAP = 0x00100000 //nolint:golint
// _OPEN_TREE_CLONE - Clone the source path mount
_OPEN_TREE_CLONE = 0x00000001 //nolint:golint
// _MOVE_MOUNT_F_EMPTY_PATH - Move the path referenced by the fd
_MOVE_MOUNT_F_EMPTY_PATH = 0x00000004 //nolint:golint
)
// openTree is a wrapper for the open_tree syscall
func openTree(path string, flags int) (fd int, err error) {
var _p0 *byte
@ -61,7 +49,7 @@ func moveMount(fdTree int, target string) (err error) {
return err
}
flags := _MOVE_MOUNT_F_EMPTY_PATH
flags := unix.MOVE_MOUNT_F_EMPTY_PATH
_, _, e1 := syscall.Syscall6(uintptr(unix.SYS_MOVE_MOUNT),
uintptr(fdTree), uintptr(unsafe.Pointer(_p1)),
@ -98,14 +86,14 @@ func createIDMappedMount(source, target string, pid int) error {
}
var attr attr
attr.attrSet = _MOUNT_ATTR_IDMAP
attr.attrSet = unix.MOUNT_ATTR_IDMAP
attr.attrClr = 0
attr.propagation = 0
attr.userNs = uint64(userNsFile.Fd())
defer userNsFile.Close()
targetDirFd, err := openTree(source, _OPEN_TREE_CLONE|unix.AT_RECURSIVE)
targetDirFd, err := openTree(source, unix.OPEN_TREE_CLONE)
if err != nil {
return err
}
@ -144,7 +132,7 @@ func createUsernsProcess(uidMaps []idtools.IDMap, gidMaps []idtools.IDMap) (int,
for _, m := range idmap {
mappings = mappings + fmt.Sprintf("%d %d %d\n", m.ContainerID, m.HostID, m.Size)
}
return ioutil.WriteFile(fmt.Sprintf("/proc/%d/%s", pid, fname), []byte(mappings), 0600)
return os.WriteFile(fmt.Sprintf("/proc/%d/%s", pid, fname), []byte(mappings), 0600)
}
if err := writeMappings("uid_map", uidMaps); err != nil {
cleanupFunc()

View File

@ -1,3 +1,6 @@
//go:build linux
// +build linux
package overlay
import jsoniter "github.com/json-iterator/go"

View File

@ -9,7 +9,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"path"
@ -34,7 +33,6 @@ import (
units "github.com/docker/go-units"
"github.com/hashicorp/go-multierror"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/runc/libcontainer/userns"
"github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus"
@ -347,7 +345,7 @@ func Init(home string, options graphdriver.Options) (graphdriver.Driver, error)
logrus.Warnf("Network file system detected as backing store. Enforcing overlay option `force_mask=\"%o\"`. Add it to storage.conf to silence this warning", m)
}
if err := ioutil.WriteFile(getMountProgramFlagFile(home), []byte("true"), 0600); err != nil {
if err := os.WriteFile(getMountProgramFlagFile(home), []byte("true"), 0600); err != nil {
return nil, err
}
} else {
@ -580,11 +578,11 @@ func cachedFeatureSet(feature string, set bool) string {
}
func cachedFeatureCheck(runhome, feature string) (supported bool, text string, err error) {
content, err := ioutil.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, true)))
content, err := os.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, true)))
if err == nil {
return true, string(content), nil
}
content, err = ioutil.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, false)))
content, err = os.ReadFile(filepath.Join(runhome, cachedFeatureSet(feature, false)))
if err == nil {
return false, string(content), nil
}
@ -608,7 +606,7 @@ func SupportsNativeOverlay(home, runhome string) (bool, error) {
}
var contents string
flagContent, err := ioutil.ReadFile(getMountProgramFlagFile(home))
flagContent, err := os.ReadFile(getMountProgramFlagFile(home))
if err == nil {
contents = strings.TrimSpace(string(flagContent))
}
@ -621,7 +619,7 @@ func SupportsNativeOverlay(home, runhome string) (bool, error) {
if err != nil && !os.IsNotExist(err) {
return false, err
}
if err := ioutil.WriteFile(getMountProgramFlagFile(home), []byte(fmt.Sprintf("%t", needsMountProgram)), 0600); err != nil && !os.IsNotExist(err) {
if err := os.WriteFile(getMountProgramFlagFile(home), []byte(fmt.Sprintf("%t", needsMountProgram)), 0600); err != nil && !os.IsNotExist(err) {
return false, err
}
if needsMountProgram {
@ -657,7 +655,7 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
logLevel = logrus.DebugLevel
}
layerDir, err := ioutil.TempDir(home, "compat")
layerDir, err := os.MkdirTemp(home, "compat")
if err != nil {
patherr, ok := err.(*os.PathError)
if ok && patherr.Err == syscall.ENOSPC {
@ -716,7 +714,7 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
logrus.Debugf("overlay: test mount with multiple lowers succeeded")
return supportsDType, nil
}
logrus.Debugf("overlay: test mount with multiple lowers failed %v", err)
logrus.Debugf("overlay: test mount with multiple lowers failed: %v", err)
}
flags = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower1Dir, upperDir, workDir)
if selinux.GetEnabled() {
@ -728,7 +726,7 @@ func supportsOverlay(home string, homeMagic graphdriver.FsMagic, rootUID, rootGI
logrus.StandardLogger().Logf(logLevel, "overlay: test mount with multiple lowers failed, but succeeded with a single lower")
return supportsDType, fmt.Errorf("kernel too old to provide multiple lowers feature for overlay: %w", graphdriver.ErrNotSupported)
}
logrus.Debugf("overlay: test mount with a single lower failed %v", err)
logrus.Debugf("overlay: test mount with a single lower failed: %v", err)
}
logrus.StandardLogger().Logf(logLevel, "'overlay' is not supported over %s at %q", backingFs, home)
return supportsDType, fmt.Errorf("'overlay' is not supported over %s at %q: %w", backingFs, home, graphdriver.ErrIncompatibleFS)
@ -1009,7 +1007,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disable
}
// Write link id to link file
if err := ioutil.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil {
if err := os.WriteFile(path.Join(dir, "link"), []byte(lid), 0644); err != nil {
return err
}
@ -1030,7 +1028,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disable
return err
}
if lower != "" {
if err := ioutil.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil {
if err := os.WriteFile(path.Join(dir, lowerFile), []byte(lower), 0666); err != nil {
return err
}
}
@ -1073,7 +1071,7 @@ func (d *Driver) getLower(parent string) (string, error) {
}
// Read Parent link fileA
parentLink, err := ioutil.ReadFile(path.Join(parentDir, "link"))
parentLink, err := os.ReadFile(path.Join(parentDir, "link"))
if err != nil {
if !os.IsNotExist(err) {
return "", err
@ -1082,14 +1080,14 @@ func (d *Driver) getLower(parent string) (string, error) {
if err := d.recreateSymlinks(); err != nil {
return "", fmt.Errorf("recreating the links: %w", err)
}
parentLink, err = ioutil.ReadFile(path.Join(parentDir, "link"))
parentLink, err = os.ReadFile(path.Join(parentDir, "link"))
if err != nil {
return "", err
}
}
lowers := []string{path.Join(linkDir, string(parentLink))}
parentLower, err := ioutil.ReadFile(path.Join(parentDir, lowerFile))
parentLower, err := os.ReadFile(path.Join(parentDir, lowerFile))
if err == nil {
parentLowers := strings.Split(string(parentLower), ":")
lowers = append(lowers, parentLowers...)
@ -1118,7 +1116,7 @@ func (d *Driver) dir2(id string) (string, bool) {
func (d *Driver) getLowerDirs(id string) ([]string, error) {
var lowersArray []string
lowers, err := ioutil.ReadFile(path.Join(d.dir(id), lowerFile))
lowers, err := os.ReadFile(path.Join(d.dir(id), lowerFile))
if err == nil {
for _, s := range strings.Split(string(lowers), ":") {
lower := d.dir(s)
@ -1187,7 +1185,7 @@ func (d *Driver) optsAppendMappings(opts string, uidMaps, gidMaps []idtools.IDMa
// Remove cleans the directories that are created for this id.
func (d *Driver) Remove(id string) error {
dir := d.dir(id)
lid, err := ioutil.ReadFile(path.Join(dir, "link"))
lid, err := os.ReadFile(path.Join(dir, "link"))
if err == nil {
if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil {
logrus.Debugf("Failed to remove link: %v", err)
@ -1210,7 +1208,7 @@ func (d *Driver) recreateSymlinks() error {
const maxIterations = 10
// List all the directories under the home directory
dirs, err := ioutil.ReadDir(d.home)
dirs, err := os.ReadDir(d.home)
if err != nil {
return fmt.Errorf("reading driver home directory %q: %w", d.home, err)
}
@ -1229,11 +1227,11 @@ func (d *Driver) recreateSymlinks() error {
// the layer's "link" file that points to the layer's "diff" directory.
for _, dir := range dirs {
// Skip over the linkDir and anything that is not a directory
if dir.Name() == linkDir || !dir.Mode().IsDir() {
if dir.Name() == linkDir || !dir.IsDir() {
continue
}
// Read the "link" file under each layer to get the name of the symlink
data, err := ioutil.ReadFile(path.Join(d.dir(dir.Name()), "link"))
data, err := os.ReadFile(path.Join(d.dir(dir.Name()), "link"))
if err != nil {
errs = multierror.Append(errs, fmt.Errorf("reading name of symlink for %q: %w", dir.Name(), err))
continue
@ -1258,7 +1256,7 @@ func (d *Driver) recreateSymlinks() error {
linkDirFullPath := filepath.Join(d.home, "l")
// Now check if we somehow lost a "link" file, by making sure
// that each symlink we have corresponds to one.
links, err := ioutil.ReadDir(linkDirFullPath)
links, err := os.ReadDir(linkDirFullPath)
if err != nil {
errs = multierror.Append(errs, err)
continue
@ -1288,11 +1286,11 @@ func (d *Driver) recreateSymlinks() error {
// it has the basename of our symlink in it.
targetID := targetComponents[1]
linkFile := filepath.Join(d.dir(targetID), "link")
data, err := ioutil.ReadFile(linkFile)
data, err := os.ReadFile(linkFile)
if err != nil || string(data) != link.Name() {
// NOTE: If two or more links point to the same target, we will update linkFile
// with every value of link.Name(), and set madeProgress = true every time.
if err := ioutil.WriteFile(linkFile, []byte(link.Name()), 0644); err != nil {
if err := os.WriteFile(linkFile, []byte(link.Name()), 0644); err != nil {
errs = multierror.Append(errs, fmt.Errorf("correcting link for layer %s: %w", targetID, err))
continue
}
@ -1312,7 +1310,7 @@ func (d *Driver) recreateSymlinks() error {
}
// Get creates and mounts the required file system for the given id and returns the mount path.
func (d *Driver) Get(id string, options graphdriver.MountOpts) (_ string, retErr error) {
func (d *Driver) Get(id string, options graphdriver.MountOpts) (string, error) {
return d.get(id, false, options)
}
@ -1346,7 +1344,16 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
}
if !d.usingMetacopy {
if hasMetacopyOption(optsList) {
logrus.StandardLogger().Logf(logLevel, "Ignoring global metacopy option, not supported with booted kernel")
if d.options.mountProgram == "" {
release := ""
var uts unix.Utsname
if err := unix.Uname(&uts); err == nil {
release = " " + string(uts.Release[:]) + " " + string(uts.Version[:])
}
logrus.StandardLogger().Logf(logLevel, "Ignoring global metacopy option, not supported with booted kernel"+release)
} else {
logrus.Debugf("Ignoring global metacopy option, the mount program doesn't support it")
}
}
optsList = stripOption(optsList, "metacopy=on")
}
@ -1358,7 +1365,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
}
}
lowers, err := ioutil.ReadFile(path.Join(dir, lowerFile))
lowers, err := os.ReadFile(path.Join(dir, lowerFile))
if err != nil && !os.IsNotExist(err) {
return "", err
}
@ -1374,7 +1381,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
// Check if $link/../diff{1-*} exist. If they do, add them, in order, as the front of the lowers
// lists that we're building. "diff" itself is the upper, so it won't be in the lists.
link, err := ioutil.ReadFile(path.Join(dir, "link"))
link, err := os.ReadFile(path.Join(dir, "link"))
if err != nil {
if !os.IsNotExist(err) {
return "", err
@ -1383,7 +1390,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
if err := d.recreateSymlinks(); err != nil {
return "", fmt.Errorf("recreating the links: %w", err)
}
link, err = ioutil.ReadFile(path.Join(dir, "link"))
link, err = os.ReadFile(path.Join(dir, "link"))
if err != nil {
return "", err
}
@ -1608,7 +1615,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
diffDir := path.Join(id, "diff")
opts = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(relLowers, ":"), diffDir, workdir)
} else {
opts = fmt.Sprintf("lowerdir=%s", strings.Join(relLowers, ":"))
opts = fmt.Sprintf("lowerdir=%s:%s", diffDir, strings.Join(relLowers, ":"))
}
if len(optsList) > 0 {
opts = fmt.Sprintf("%s,%s", opts, strings.Join(optsList, ","))
@ -1649,7 +1656,7 @@ func (d *Driver) Put(id string) error {
if count := d.ctr.Decrement(mountpoint); count > 0 {
return nil
}
if _, err := ioutil.ReadFile(path.Join(dir, lowerFile)); err != nil && !os.IsNotExist(err) {
if _, err := os.ReadFile(path.Join(dir, lowerFile)); err != nil && !os.IsNotExist(err) {
return err
}
@ -1658,7 +1665,7 @@ func (d *Driver) Put(id string) error {
mappedRoot := filepath.Join(d.home, id, "mapped")
// It should not happen, but cleanup any mapped mount if it was leaked.
if _, err := os.Stat(mappedRoot); err == nil {
mounts, err := ioutil.ReadDir(mappedRoot)
mounts, err := os.ReadDir(mappedRoot)
if err == nil {
// Go through all of the mapped mounts.
for _, m := range mounts {
@ -1806,7 +1813,7 @@ func (d *Driver) ApplyDiffWithDiffer(id, parent string, options *graphdriver.App
if err != nil && !os.IsExist(err) {
return graphdriver.DriverWithDifferOutput{}, err
}
applyDir, err = ioutil.TempDir(d.getStagingDir(), "")
applyDir, err = os.MkdirTemp(d.getStagingDir(), "")
if err != nil {
return graphdriver.DriverWithDifferOutput{}, err
}
@ -1826,7 +1833,7 @@ func (d *Driver) ApplyDiffWithDiffer(id, parent string, options *graphdriver.App
GIDMaps: idMappings.GIDs(),
IgnoreChownErrors: d.options.ignoreChownErrors,
WhiteoutFormat: d.getWhiteoutFormat(),
InUserNS: userns.RunningInUserNS(),
InUserNS: unshare.IsRootless(),
})
out.Target = applyDir
return out, err
@ -1884,7 +1891,7 @@ func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts)
IgnoreChownErrors: d.options.ignoreChownErrors,
ForceMask: d.options.forceMask,
WhiteoutFormat: d.getWhiteoutFormat(),
InUserNS: userns.RunningInUserNS(),
InUserNS: unshare.IsRootless(),
}); err != nil {
return 0, err
}
@ -2167,7 +2174,7 @@ func (al *additionalLayer) CreateAs(id, parent string) error {
}
// tell the additional layer store that we use this layer.
// mark this layer as "additional layer"
if err := ioutil.WriteFile(path.Join(dir, "additionallayer"), []byte(al.path), 0644); err != nil {
if err := os.WriteFile(path.Join(dir, "additionallayer"), []byte(al.path), 0644); err != nil {
return err
}
notifyUseAdditionalLayer(al.path)
@ -2175,7 +2182,7 @@ func (al *additionalLayer) CreateAs(id, parent string) error {
}
func (d *Driver) getAdditionalLayerPathByID(id string) (string, error) {
al, err := ioutil.ReadFile(path.Join(d.dir(id), "additionallayer"))
al, err := os.ReadFile(path.Join(d.dir(id), "additionallayer"))
if err != nil {
return "", err
}

View File

@ -52,7 +52,6 @@ struct fsxattr {
import "C"
import (
"fmt"
"io/ioutil"
"math"
"os"
"path"
@ -123,11 +122,9 @@ func generateUniqueProjectID(path string) (uint32, error) {
// This is a way to prevent xfs_quota management from conflicting with
// containers/storage.
//
// Then try to create a test directory with the next project id and set a quota
// on it. If that works, continue to scan existing containers to map allocated
// project ids.
//
func NewControl(basePath string) (*Control, error) {
//
// Get project id of parent dir as minimal id to be used by driver
@ -336,7 +333,7 @@ func setProjectID(targetPath string, projectID uint32) error {
// findNextProjectID - find the next project id to be used for containers
// by scanning driver home directory to find used project ids
func (q *Control) findNextProjectID(home string) error {
files, err := ioutil.ReadDir(home)
files, err := os.ReadDir(home)
if err != nil {
return fmt.Errorf("read directory failed : %s", home)
}

View File

@ -10,7 +10,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
@ -24,7 +23,7 @@ import (
"github.com/Microsoft/go-winio"
"github.com/Microsoft/go-winio/backuptar"
"github.com/Microsoft/hcsshim"
"github.com/containers/storage/drivers"
graphdriver "github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/directory"
"github.com/containers/storage/pkg/idtools"
@ -475,7 +474,7 @@ func (d *Driver) Put(id string) error {
// We use this opportunity to cleanup any -removing folders which may be
// still left if the daemon was killed while it was removing a layer.
func (d *Driver) Cleanup() error {
items, err := ioutil.ReadDir(d.info.HomeDir)
items, err := os.ReadDir(d.info.HomeDir)
if err != nil {
if os.IsNotExist(err) {
return nil
@ -870,7 +869,7 @@ func writeLayer(layerData io.Reader, home string, id string, parentLayerPaths ..
// resolveID computes the layerID information based on the given id.
func (d *Driver) resolveID(id string) (string, error) {
content, err := ioutil.ReadFile(filepath.Join(d.dir(id), "layerID"))
content, err := os.ReadFile(filepath.Join(d.dir(id), "layerID"))
if os.IsNotExist(err) {
return id, nil
} else if err != nil {
@ -881,13 +880,13 @@ func (d *Driver) resolveID(id string) (string, error) {
// setID stores the layerId in disk.
func (d *Driver) setID(id, altID string) error {
return ioutil.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altID), 0600)
return os.WriteFile(filepath.Join(d.dir(id), "layerId"), []byte(altID), 0600)
}
// getLayerChain returns the layer chain information.
func (d *Driver) getLayerChain(id string) ([]string, error) {
jPath := filepath.Join(d.dir(id), "layerchain.json")
content, err := ioutil.ReadFile(jPath)
content, err := os.ReadFile(jPath)
if os.IsNotExist(err) {
return nil, nil
} else if err != nil {
@ -911,7 +910,7 @@ func (d *Driver) setLayerChain(id string, chain []string) error {
}
jPath := filepath.Join(d.dir(id), "layerchain.json")
err = ioutil.WriteFile(jPath, content, 0600)
err = os.WriteFile(jPath, content, 0600)
if err != nil {
return fmt.Errorf("unable to write layerchain file - %s", err)
}

View File

@ -18,7 +18,7 @@ import (
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/mount"
"github.com/containers/storage/pkg/parsers"
"github.com/mistifyio/go-zfs"
zfs "github.com/mistifyio/go-zfs/v3"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"

View File

@ -3,7 +3,6 @@ package storage
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -242,8 +241,8 @@ func (i *Image) recomputeDigests() error {
if !bigDataNameIsManifest(name) {
continue
}
if digest.Validate() != nil {
return fmt.Errorf("validating digest %q for big data item %q: %w", string(digest), name, digest.Validate())
if err := digest.Validate(); err != nil {
return fmt.Errorf("validating digest %q for big data item %q: %w", string(digest), name, err)
}
// Deduplicate the digest values.
if _, known := digests[digest]; !known {
@ -261,7 +260,7 @@ func (i *Image) recomputeDigests() error {
func (r *imageStore) Load() error {
shouldSave := false
rpath := r.imagespath()
data, err := ioutil.ReadFile(rpath)
data, err := os.ReadFile(rpath)
if err != nil && !os.IsNotExist(err) {
return err
}
@ -636,7 +635,7 @@ func (r *imageStore) BigData(id, key string) ([]byte, error) {
if !ok {
return nil, fmt.Errorf("locating image with ID %q: %w", id, ErrImageUnknown)
}
return ioutil.ReadFile(r.datapath(image.ID, key))
return os.ReadFile(r.datapath(image.ID, key))
}
func (r *imageStore) BigDataSize(id, key string) (int64, error) {

View File

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
@ -344,7 +343,15 @@ func (r *layerStore) layerspath() string {
func (r *layerStore) Load() error {
shouldSave := false
rpath := r.layerspath()
data, err := ioutil.ReadFile(rpath)
info, err := os.Stat(rpath)
if err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
r.layerspathModified = info.ModTime()
}
data, err := os.ReadFile(rpath)
if err != nil && !os.IsNotExist(err) {
return err
}
@ -435,7 +442,7 @@ func (r *layerStore) LoadLocked() error {
func (r *layerStore) loadMounts() error {
mounts := make(map[string]*Layer)
mpath := r.mountspath()
data, err := ioutil.ReadFile(mpath)
data, err := os.ReadFile(mpath)
if err != nil && !os.IsNotExist(err) {
return err
}
@ -556,6 +563,8 @@ func (s *store) newLayerStore(rundir string, layerdir string, driver drivers.Dri
uidMap: copyIDMap(s.uidMap),
gidMap: copyIDMap(s.gidMap),
}
rlstore.Lock()
defer rlstore.Unlock()
if err := rlstore.Load(); err != nil {
return nil, err
}
@ -577,6 +586,8 @@ func newROLayerStore(rundir string, layerdir string, driver drivers.Driver) (ROL
bymount: make(map[string]*Layer),
byname: make(map[string]*Layer),
}
rlstore.RLock()
defer rlstore.Unlock()
if err := rlstore.Load(); err != nil {
return nil, err
}
@ -746,7 +757,7 @@ func (r *layerStore) Put(id string, parentLayer *Layer, names []string, mountLab
templateUncompressedDigest, templateUncompressedSize = templateLayer.UncompressedDigest, templateLayer.UncompressedSize
templateCompressionType = templateLayer.CompressionType
templateUIDs, templateGIDs = append([]uint32{}, templateLayer.UIDs...), append([]uint32{}, templateLayer.GIDs...)
templateTSdata, tserr = ioutil.ReadFile(r.tspath(templateLayer.ID))
templateTSdata, tserr = os.ReadFile(r.tspath(templateLayer.ID))
if tserr != nil && !os.IsNotExist(tserr) {
return nil, -1, tserr
}
@ -1381,6 +1392,9 @@ func (r *layerStore) Wipe() error {
for id := range r.byid {
ids = append(ids, id)
}
sort.Slice(ids, func(i, j int) bool {
return r.byid[ids[i]].Created.After(r.byid[ids[j]].Created)
})
for _, id := range ids {
if err := r.Delete(id); err != nil {
return err
@ -1660,7 +1674,7 @@ func (r *layerStore) applyDiffWithOptions(to string, layerOptions *LayerOptions,
if compressedDigester != nil {
compressedWriter = compressedDigester.Hash()
} else {
compressedWriter = ioutil.Discard
compressedWriter = io.Discard
}
compressedCounter := ioutils.NewWriteCounter(compressedWriter)
defragmented = io.TeeReader(defragmented, compressedCounter)
@ -1924,7 +1938,6 @@ func (r *layerStore) Modified() (bool, error) {
}
if info != nil {
tmodified = info.ModTime() != r.layerspathModified
r.layerspathModified = info.ModTime()
}
return tmodified, nil

View File

@ -9,7 +9,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -25,7 +24,6 @@ import (
"github.com/containers/storage/pkg/system"
"github.com/containers/storage/pkg/unshare"
gzip "github.com/klauspost/pgzip"
"github.com/opencontainers/runc/libcontainer/userns"
"github.com/sirupsen/logrus"
"github.com/ulikunitz/xz"
)
@ -77,6 +75,7 @@ const (
solaris = "solaris"
windows = "windows"
darwin = "darwin"
freebsd = "freebsd"
)
var xattrsToIgnore = map[string]interface{}{
@ -484,7 +483,7 @@ func newTarAppender(idMapping *idtools.IDMappings, writer io.Writer, chownOpts *
}
// canonicalTarName provides a platform-independent and consistent posix-style
//path for files and directories to be archived regardless of the platform.
// path for files and directories to be archived regardless of the platform.
func canonicalTarName(name string, isDir bool) (string, error) {
name, err := CanonicalTarNameForPath(name)
if err != nil {
@ -673,7 +672,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L
if !strings.HasPrefix(targetPath, extractDir) {
return breakoutError(fmt.Errorf("invalid hardlink %q -> %q", targetPath, hdr.Linkname))
}
if err := os.Link(targetPath, path); err != nil {
if err := handleLLink(targetPath, path); err != nil {
return err
}
@ -1107,7 +1106,9 @@ loop:
// Untar reads a stream of bytes from `archive`, parses it as a tar archive,
// and unpacks it into the directory at `dest`.
// The archive may be compressed with one of the following algorithms:
// identity (uncompressed), gzip, bzip2, xz.
//
// identity (uncompressed), gzip, bzip2, xz.
//
// FIXME: specify behavior when target path exists vs. doesn't exist.
func Untar(tarArchive io.Reader, dest string, options *TarOptions) error {
return untarHandler(tarArchive, dest, options, true)
@ -1159,7 +1160,7 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
GIDMaps: tarMappings.GIDs(),
Compression: Uncompressed,
CopyPass: true,
InUserNS: userns.RunningInUserNS(),
InUserNS: unshare.IsRootless(),
}
archive, err := TarWithOptions(src, options)
if err != nil {
@ -1174,7 +1175,7 @@ func (archiver *Archiver) TarUntar(src, dst string) error {
UIDMaps: untarMappings.UIDs(),
GIDMaps: untarMappings.GIDs(),
ChownOpts: archiver.ChownOpts,
InUserNS: userns.RunningInUserNS(),
InUserNS: unshare.IsRootless(),
}
return archiver.Untar(archive, dst, options)
}
@ -1194,7 +1195,7 @@ func (archiver *Archiver) UntarPath(src, dst string) error {
UIDMaps: untarMappings.UIDs(),
GIDMaps: untarMappings.GIDs(),
ChownOpts: archiver.ChownOpts,
InUserNS: userns.RunningInUserNS(),
InUserNS: unshare.IsRootless(),
}
return archiver.Untar(archive, dst, options)
}
@ -1294,7 +1295,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
UIDMaps: archiver.UntarIDMappings.UIDs(),
GIDMaps: archiver.UntarIDMappings.GIDs(),
ChownOpts: archiver.ChownOpts,
InUserNS: userns.RunningInUserNS(),
InUserNS: unshare.IsRootless(),
NoOverwriteDirNonDir: true,
}
err = archiver.Untar(r, filepath.Dir(dst), options)
@ -1348,7 +1349,7 @@ func remapIDs(readIDMappings, writeIDMappings *idtools.IDMappings, chownOpts *id
// of that file as an archive. The archive can only be read once - as soon as reading completes,
// the file will be deleted.
func NewTempArchive(src io.Reader, dir string) (*TempArchive, error) {
f, err := ioutil.TempFile(dir, "")
f, err := os.CreateTemp(dir, "")
if err != nil {
return nil, err
}
@ -1472,7 +1473,7 @@ func CopyFileWithTarAndChown(chownOpts *idtools.IDPair, hasher io.Writer, uidmap
err = fmt.Errorf("extracting data to %q while copying: %w", dest, err)
}
hashWorker.Wait()
if err == nil {
if err == nil && hashError != nil {
err = fmt.Errorf("calculating digest of data for %q while copying: %w", dest, hashError)
}
return err

View File

@ -1,3 +1,4 @@
//go:build freebsd
// +build freebsd
package archive
@ -8,10 +9,11 @@ import (
"os"
"path/filepath"
"syscall"
"unsafe"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
"github.com/opencontainers/runc/libcontainer/userns"
"github.com/containers/storage/pkg/unshare"
"golang.org/x/sys/unix"
)
@ -87,7 +89,7 @@ func minor(device uint64) uint64 {
// handleTarTypeBlockCharFifo is an OS-specific helper function used by
// createTarFile to handle the following types of header: Block; Char; Fifo
func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
if userns.RunningInUserNS() {
if unshare.IsRootless() {
// cannot create a device if running in user namespace
return nil
}
@ -110,16 +112,18 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *
if forceMask != nil {
permissionsMask = *forceMask
}
if hdr.Typeflag == tar.TypeLink {
if fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {
if err := os.Chmod(path, permissionsMask); err != nil {
return err
}
}
} else if hdr.Typeflag != tar.TypeSymlink {
if err := os.Chmod(path, permissionsMask); err != nil {
return err
}
p, err := unix.BytePtrFromString(path)
if err != nil {
return err
}
_, _, e1 := unix.Syscall(unix.SYS_LCHMOD, uintptr(unsafe.Pointer(p)), uintptr(permissionsMask), 0)
if e1 != 0 {
return e1
}
return nil
}
// Hardlink without following symlinks
func handleLLink(targetPath string, path string) error {
return unix.Linkat(unix.AT_FDCWD, targetPath, unix.AT_FDCWD, path, 0)
}

View File

@ -1,3 +1,4 @@
//go:build !windows && !freebsd
// +build !windows,!freebsd
package archive
@ -97,7 +98,7 @@ func handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {
mode |= unix.S_IFIFO
}
return system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor)))
return system.Mknod(path, mode, system.Mkdev(hdr.Devmajor, hdr.Devminor))
}
func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *os.FileMode) error {
@ -118,3 +119,13 @@ func handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo, forceMask *
}
return nil
}
// Hardlink without symlinks
func handleLLink(targetPath, path string) error {
// Note: on Linux, the link syscall will not follow symlinks.
// This behavior is implementation-dependent since
// POSIX.1-2008 so to make it clear that we need non-symlink
// following here we use the linkat syscall which has a flags
// field to select symlink following or not.
return unix.Linkat(unix.AT_FDCWD, targetPath, unix.AT_FDCWD, path, 0)
}

View File

@ -78,3 +78,8 @@ func getFileUIDGID(stat interface{}) (idtools.IDPair, error) {
// no notion of file ownership mapping yet on Windows
return idtools.IDPair{0, 0}, nil
}
// Hardlink without following symlinks
func handleLLink(targetPath string, path string) error {
return os.Link(targetPath, path)
}

View File

@ -5,7 +5,6 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
@ -403,7 +402,7 @@ func ChangesDirs(newDir string, newMappings *idtools.IDMappings, oldDir string,
oldRoot, newRoot *FileInfo
)
if oldDir == "" {
emptyDir, err := ioutil.TempDir("", "empty")
emptyDir, err := os.MkdirTemp("", "empty")
if err != nil {
return nil, err
}

View File

@ -4,7 +4,6 @@ import (
"archive/tar"
"errors"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
@ -255,7 +254,7 @@ func PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo CopyInfo) (dstDir
// The destination exists as a directory. No alteration
// to srcContent is needed as its contents can be
// simply extracted to the destination directory.
return dstInfo.Path, ioutil.NopCloser(srcContent), nil
return dstInfo.Path, io.NopCloser(srcContent), nil
case dstInfo.Exists && srcInfo.IsDir:
// The destination exists as some type of file and the source
// content is a directory. This is an error condition since

View File

@ -5,7 +5,6 @@ import (
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -102,7 +101,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64,
basename := filepath.Base(hdr.Name)
aufsHardlinks[basename] = hdr
if aufsTempdir == "" {
if aufsTempdir, err = ioutil.TempDir("", "storageplnk"); err != nil {
if aufsTempdir, err = os.MkdirTemp("", "storageplnk"); err != nil {
return 0, err
}
defer os.RemoveAll(aufsTempdir)

View File

@ -4,14 +4,13 @@ import (
stdtar "archive/tar"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"sync"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/idtools"
"github.com/opencontainers/runc/libcontainer/userns"
"github.com/containers/storage/pkg/unshare"
)
// NewArchiver returns a new Archiver which uses chrootarchive.Untar
@ -31,7 +30,8 @@ func NewArchiverWithChown(tarIDMappings *idtools.IDMappings, chownOpts *idtools.
// Untar reads a stream of bytes from `archive`, parses it as a tar archive,
// and unpacks it into the directory at `dest`.
// The archive may be compressed with one of the following algorithms:
// identity (uncompressed), gzip, bzip2, xz.
//
// identity (uncompressed), gzip, bzip2, xz.
func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error {
return untarHandler(tarArchive, dest, options, true, dest)
}
@ -66,7 +66,7 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions
}
if options == nil {
options = &archive.TarOptions{}
options.InUserNS = userns.RunningInUserNS()
options.InUserNS = unshare.IsRootless()
}
if options.ExcludePatterns == nil {
options.ExcludePatterns = []string{}
@ -82,7 +82,7 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions
}
}
r := ioutil.NopCloser(tarArchive)
r := io.NopCloser(tarArchive)
if decompress {
decompressedArchive, err := archive.DecompressStream(tarArchive)
if err != nil {
@ -136,7 +136,7 @@ func CopyFileWithTarAndChown(chownOpts *idtools.IDPair, hasher io.Writer, uidmap
err = fmt.Errorf("extracting data to %q while copying: %w", dest, err)
}
hashWorker.Wait()
if err == nil {
if err == nil && hashError != nil {
err = fmt.Errorf("calculating digest of data for %q while copying: %w", dest, hashError)
}
return err

View File

@ -9,7 +9,6 @@ import (
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -111,7 +110,7 @@ func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.T
// when `xz -d -c -q | storage-untar ...` failed on storage-untar side,
// we need to exhaust `xz`'s output, otherwise the `xz` side will be
// pending on write pipe forever
io.Copy(ioutil.Discard, decompressedArchive)
io.Copy(io.Discard, decompressedArchive)
return fmt.Errorf("processing tar file(%s): %w", output, err)
}

View File

@ -2,7 +2,6 @@ package chrootarchive
import (
"fmt"
"io/ioutil"
"net"
"os"
"os/user"
@ -51,7 +50,7 @@ func chroot(path string) (err error) {
}
// setup oldRoot for pivot_root
pivotDir, err := ioutil.TempDir(path, ".pivot_root")
pivotDir, err := os.MkdirTemp(path, ".pivot_root")
if err != nil {
return fmt.Errorf("setting up pivot dir: %w", err)
}

View File

@ -3,7 +3,6 @@ package chrootarchive
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -26,7 +25,7 @@ func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions
layer = decompressed
}
tmpDir, err := ioutil.TempDir(os.Getenv("temp"), "temp-storage-extract")
tmpDir, err := os.MkdirTemp(os.Getenv("temp"), "temp-storage-extract")
if err != nil {
return 0, fmt.Errorf("ApplyLayer failed to create temp-storage-extract under %s. %s", dest, err)
}

View File

@ -8,7 +8,6 @@ import (
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@ -16,7 +15,7 @@ import (
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/reexec"
"github.com/containers/storage/pkg/system"
"github.com/opencontainers/runc/libcontainer/userns"
"github.com/containers/storage/pkg/unshare"
)
type applyLayerResponse struct {
@ -36,7 +35,7 @@ func applyLayer() {
runtime.LockOSThread()
flag.Parse()
inUserns := userns.RunningInUserNS()
inUserns := unshare.IsRootless()
if err := chroot(flag.Arg(0)); err != nil {
fatal(err)
}
@ -56,7 +55,7 @@ func applyLayer() {
options.InUserNS = true
}
if tmpDir, err = ioutil.TempDir("/", "temp-storage-extract"); err != nil {
if tmpDir, err = os.MkdirTemp("/", "temp-storage-extract"); err != nil {
fatal(err)
}
@ -95,7 +94,7 @@ func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions
}
if options == nil {
options = &archive.TarOptions{}
if userns.RunningInUserNS() {
if unshare.IsRootless() {
options.InUserNS = true
}
}
@ -110,7 +109,7 @@ func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions
cmd := reexec.Command("storage-applyLayer", dest)
cmd.Stdin = layer
cmd.Env = append(cmd.Env, fmt.Sprintf("OPT=%s", data))
cmd.Env = append(os.Environ(), fmt.Sprintf("OPT=%s", data))
outBuf, errBuf := new(bytes.Buffer), new(bytes.Buffer)
cmd.Stdout, cmd.Stderr = outBuf, errBuf

View File

@ -3,7 +3,6 @@ package chrootarchive
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -30,7 +29,7 @@ func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions
layer = decompressed
}
tmpDir, err := ioutil.TempDir(os.Getenv("temp"), "temp-storage-extract")
tmpDir, err := os.MkdirTemp(os.Getenv("temp"), "temp-storage-extract")
if err != nil {
return 0, fmt.Errorf("ApplyLayer failed to create temp-storage-extract under %s. %s", dest, err)
}

View File

@ -1,3 +1,4 @@
//go:build !windows && !darwin
// +build !windows,!darwin
package chrootarchive
@ -5,7 +6,6 @@ package chrootarchive
import (
"fmt"
"io"
"io/ioutil"
"os"
"github.com/containers/storage/pkg/reexec"
@ -25,5 +25,5 @@ func fatal(err error) {
// flush consumes all the bytes from the reader discarding
// any errors
func flush(r io.Reader) (bytes int64, err error) {
return io.Copy(ioutil.Discard, r)
return io.Copy(io.Discard, r)
}

View File

@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"sort"
"strconv"
@ -128,7 +127,7 @@ func (c *layersCache) load() error {
}
defer manifestReader.Close()
manifest, err := ioutil.ReadAll(manifestReader)
manifest, err := io.ReadAll(manifestReader)
if err != nil {
return fmt.Errorf("open manifest file for layer %q: %w", r.ID, err)
}
@ -334,7 +333,7 @@ func writeCache(manifest []byte, id string, dest setBigData) (*metadata, error)
}()
defer pipeReader.Close()
counter := ioutils.NewWriteCounter(ioutil.Discard)
counter := ioutils.NewWriteCounter(io.Discard)
r := io.TeeReader(pipeReader, counter)

View File

@ -8,7 +8,6 @@ import (
"bufio"
"encoding/base64"
"io"
"io/ioutil"
"github.com/containers/storage/pkg/chunked/internal"
"github.com/containers/storage/pkg/ioutils"
@ -21,9 +20,7 @@ const holesThreshold = int64(1 << 10)
type holesFinder struct {
reader *bufio.Reader
fileOff int64
zeros int64
from int64
threshold int64
state int
@ -432,7 +429,7 @@ func zstdChunkedWriterWithLevel(out io.Writer, metadata map[string]string, level
go func() {
ch <- writeZstdChunkedStream(out, metadata, r, level)
io.Copy(ioutil.Discard, r)
io.Copy(io.Discard, r)
r.Close()
close(ch)
}()

View File

@ -1,7 +1,6 @@
package chunked
import (
"fmt"
"io"
)
@ -22,5 +21,5 @@ type ErrBadRequest struct {
}
func (e ErrBadRequest) Error() string {
return fmt.Sprintf("bad request")
return "bad request"
}

View File

@ -8,7 +8,6 @@ import (
"fmt"
"hash"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
@ -657,7 +656,7 @@ func (c *chunkedDiffer) prepareCompressedStreamToFile(partCompression compressed
// Only the missing chunk in the requested part refers to a hole.
// The received data must be discarded.
limitReader := io.LimitReader(from, mf.CompressedSize)
_, err := io.CopyBuffer(ioutil.Discard, limitReader, c.copyBuffer)
_, err := io.CopyBuffer(io.Discard, limitReader, c.copyBuffer)
return fileTypeHole, err
case partCompression == fileTypeZstdChunked:
c.rawReader = io.LimitReader(from, mf.CompressedSize)
@ -856,7 +855,7 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan
for _, mf := range missingPart.Chunks {
if mf.Gap > 0 {
limitReader := io.LimitReader(part, mf.Gap)
_, err := io.CopyBuffer(ioutil.Discard, limitReader, c.copyBuffer)
_, err := io.CopyBuffer(io.Discard, limitReader, c.copyBuffer)
if err != nil {
Err = err
goto exit
@ -906,7 +905,7 @@ func (c *chunkedDiffer) storeMissingFiles(streams chan io.ReadCloser, errs chan
goto exit
}
if c.rawReader != nil {
if _, err := io.CopyBuffer(ioutil.Discard, c.rawReader, c.copyBuffer); err != nil {
if _, err := io.CopyBuffer(io.Discard, c.rawReader, c.copyBuffer); err != nil {
Err = err
goto exit
}

View File

@ -1,7 +1,6 @@
package directory
import (
"io/ioutil"
"os"
"path/filepath"
)
@ -15,7 +14,7 @@ type DiskUsage struct {
// MoveToSubdir moves all contents of a directory to a subdirectory underneath the original path
func MoveToSubdir(oldpath, subdir string) error {
infos, err := ioutil.ReadDir(oldpath)
infos, err := os.ReadDir(oldpath)
if err != nil {
return err
}

View File

@ -1,10 +1,10 @@
//go:build linux || freebsd
// +build linux freebsd
package fileutils
import (
"fmt"
"io/ioutil"
"os"
"github.com/sirupsen/logrus"
@ -13,7 +13,7 @@ import (
// GetTotalUsedFds Returns the number of used File Descriptors by
// reading it via /proc filesystem.
func GetTotalUsedFds() int {
if fds, err := ioutil.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil {
if fds, err := os.ReadDir(fmt.Sprintf("/proc/%d/fd", os.Getpid())); err != nil {
logrus.Errorf("%v", err)
} else {
return len(fds)

View File

@ -1,10 +1,10 @@
//go:build linux
// +build linux
package fsutils
import (
"fmt"
"io/ioutil"
"os"
"unsafe"
@ -12,14 +12,14 @@ import (
)
func locateDummyIfEmpty(path string) (string, error) {
children, err := ioutil.ReadDir(path)
children, err := os.ReadDir(path)
if err != nil {
return "", err
}
if len(children) != 0 {
return "", nil
}
dummyFile, err := ioutil.TempFile(path, "fsutils-dummy")
dummyFile, err := os.CreateTemp(path, "fsutils-dummy")
if err != nil {
return "", err
}

View File

@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package homedir
@ -46,7 +47,7 @@ func GetShortcutString() string {
// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
func GetRuntimeDir() (string, error) {
if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {
return xdgRuntimeDir, nil
return filepath.EvalSymlinks(xdgRuntimeDir)
}
return "", errors.New("could not get XDG_RUNTIME_DIR")
}

View File

@ -3,7 +3,6 @@ package idtools
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"os/user"
"runtime"
@ -219,7 +218,7 @@ func getOverflowUID() int {
overflowUIDOnce.Do(func() {
// 65534 is the value on older kernels where /proc/sys/kernel/overflowuid is not present
overflowUID = 65534
if content, err := ioutil.ReadFile("/proc/sys/kernel/overflowuid"); err == nil {
if content, err := os.ReadFile("/proc/sys/kernel/overflowuid"); err == nil {
if tmp, err := strconv.Atoi(string(content)); err == nil {
overflowUID = tmp
}
@ -233,7 +232,7 @@ func getOverflowGID() int {
overflowGIDOnce.Do(func() {
// 65534 is the value on older kernels where /proc/sys/kernel/overflowgid is not present
overflowGID = 65534
if content, err := ioutil.ReadFile("/proc/sys/kernel/overflowgid"); err == nil {
if content, err := os.ReadFile("/proc/sys/kernel/overflowgid"); err == nil {
if tmp, err := strconv.Atoi(string(content)); err == nil {
overflowGID = tmp
}

View File

@ -2,7 +2,6 @@ package ioutils
import (
"io"
"io/ioutil"
"os"
"path/filepath"
)
@ -28,7 +27,7 @@ func SetDefaultOptions(opts AtomicFileWriterOptions) {
// temporary file and closing it atomically changes the temporary file to
// destination path. Writing and closing concurrently is not allowed.
func NewAtomicFileWriterWithOpts(filename string, perm os.FileMode, opts *AtomicFileWriterOptions) (io.WriteCloser, error) {
f, err := ioutil.TempFile(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
f, err := os.CreateTemp(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
if err != nil {
return nil, err
}
@ -124,7 +123,7 @@ type AtomicWriteSet struct {
// commit. If no temporary directory is given the system
// default is used.
func NewAtomicWriteSet(tmpDir string) (*AtomicWriteSet, error) {
td, err := ioutil.TempDir(tmpDir, "write-set-")
td, err := os.MkdirTemp(tmpDir, "write-set-")
if err != nil {
return nil, err
}

View File

@ -1,10 +1,11 @@
//go:build !windows
// +build !windows
package ioutils
import "io/ioutil"
import "os"
// TempDir on Unix systems is equivalent to ioutil.TempDir.
// TempDir on Unix systems is equivalent to os.MkdirTemp.
func TempDir(dir, prefix string) (string, error) {
return ioutil.TempDir(dir, prefix)
return os.MkdirTemp(dir, prefix)
}

View File

@ -1,16 +1,17 @@
//go:build windows
// +build windows
package ioutils
import (
"io/ioutil"
"os"
"github.com/containers/storage/pkg/longpath"
)
// TempDir is the equivalent of ioutil.TempDir, except that the result is in Windows longpath format.
// TempDir is the equivalent of os.MkdirTemp, except that the result is in Windows longpath format.
func TempDir(dir, prefix string) (string, error) {
tempDir, err := ioutil.TempDir(dir, prefix)
tempDir, err := os.MkdirTemp(dir, prefix)
if err != nil {
return "", err
}

View File

@ -65,19 +65,19 @@ func newLastWriterID() []byte {
}
// openLock opens the file at path and returns the corresponding file
// descriptor. Note that the path is opened read-only when ro is set. If ro
// is unset, openLock will open the path read-write and create the file if
// necessary.
// descriptor. The path is opened either read-only or read-write,
// depending on the value of ro argument.
//
// openLock will create the file and its parent directories,
// if necessary.
func openLock(path string, ro bool) (fd int, err error) {
flags := unix.O_CLOEXEC | os.O_CREATE
if ro {
fd, err = unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC|os.O_CREATE, 0)
flags |= os.O_RDONLY
} else {
fd, err = unix.Open(path,
os.O_RDWR|unix.O_CLOEXEC|os.O_CREATE,
unix.S_IRUSR|unix.S_IWUSR|unix.S_IRGRP|unix.S_IROTH,
)
flags |= os.O_RDWR
}
fd, err = unix.Open(path, flags, 0o644)
if err == nil {
return
}
@ -91,7 +91,7 @@ func openLock(path string, ro bool) (fd int, err error) {
return openLock(path, ro)
}
return
return fd, &os.PathError{Op: "open", Path: path, Err: err}
}
// createLockerForPath returns a Locker object, possibly (depending on the platform)
@ -158,7 +158,7 @@ func (l *lockfile) lock(lType int16, recursive bool) {
// If we're the first reference on the lock, we need to open the file again.
fd, err := openLock(l.file, l.ro)
if err != nil {
panic(fmt.Sprintf("error opening %q: %v", l.file, err))
panic(err)
}
l.fd = uintptr(fd)

View File

@ -4,6 +4,7 @@
package system
import (
"errors"
"fmt"
"unsafe"
@ -70,7 +71,7 @@ func ReadMemInfo() (*MemInfo, error) {
}
if MemTotal < 0 || MemFree < 0 || SwapTotal < 0 || SwapFree < 0 {
return nil, fmt.Errorf("getting system memory info %w", err)
return nil, errors.New("getting system memory info")
}
meminfo := &MemInfo{}

View File

@ -1,3 +1,4 @@
//go:build !windows && !freebsd
// +build !windows,!freebsd
package system
@ -8,8 +9,8 @@ import (
// Mknod creates a filesystem node (file, device special file or named pipe) named path
// with attributes specified by mode and dev.
func Mknod(path string, mode uint32, dev int) error {
return unix.Mknod(path, mode, dev)
func Mknod(path string, mode uint32, dev uint32) error {
return unix.Mknod(path, mode, int(dev))
}
// Mkdev is used to build the value of linux devices (in /dev/) which specifies major

View File

@ -1,3 +1,4 @@
//go:build freebsd
// +build freebsd
package system
@ -17,6 +18,6 @@ func Mknod(path string, mode uint32, dev uint64) error {
// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes.
// They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major,
// then the top 12 bits of the minor.
func Mkdev(major int64, minor int64) uint32 {
return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff))
func Mkdev(major int64, minor int64) uint64 {
return uint64(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff))
}

View File

@ -35,6 +35,9 @@ func EnsureRemoveAll(dir string) error {
}
for {
if err := resetFileFlags(dir); err != nil {
return fmt.Errorf("resetting file flags: %w", err)
}
err := os.RemoveAll(dir)
if err == nil {
return nil

View File

@ -0,0 +1,10 @@
//go:build !freebsd
// +build !freebsd
package system
// Reset file flags in a directory tree. This allows EnsureRemoveAll
// to delete trees which have the immutable flag set.
func resetFileFlags(dir string) error {
return nil
}

View File

@ -0,0 +1,32 @@
package system
import (
"io/fs"
"path/filepath"
"unsafe"
"golang.org/x/sys/unix"
)
func lchflags(path string, flags int) (err error) {
p, err := unix.BytePtrFromString(path)
if err != nil {
return err
}
_, _, e1 := unix.Syscall(unix.SYS_LCHFLAGS, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
if e1 != 0 {
return e1
}
return nil
}
// Reset file flags in a directory tree. This allows EnsureRemoveAll
// to delete trees which have the immutable flag set.
func resetFileFlags(dir string) error {
return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if err := lchflags(path, 0); err != nil {
return err
}
return nil
})
}

View File

@ -10,13 +10,14 @@ import (
// LUtimesNano is used to change access and modification time of the specified path.
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
func LUtimesNano(path string, ts []syscall.Timespec) error {
atFdCwd := unix.AT_FDCWD
var _path *byte
_path, err := unix.BytePtrFromString(path)
if err != nil {
return err
}
if _, _, err := unix.Syscall(unix.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != unix.ENOSYS {
if _, _, err := unix.Syscall6(unix.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), unix.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 && err != unix.ENOSYS {
return err
}

View File

@ -5,7 +5,7 @@ package unshare
// #cgo CFLAGS: -Wall
// extern void _containers_unshare(void);
// void __attribute__((constructor)) init(void) {
// static void __attribute__((constructor)) init(void) {
// _containers_unshare();
// }
import "C"

View File

@ -4,7 +4,7 @@ package unshare
// #cgo CFLAGS: -Wall -Wextra
// extern void _containers_unshare(void);
// void __attribute__((constructor)) init(void) {
// static void __attribute__((constructor)) init(void) {
// _containers_unshare();
// }
import "C"

View File

@ -387,10 +387,41 @@ const (
UsernsEnvName = "_CONTAINERS_USERNS_CONFIGURED"
)
// hasFullUsersMappings checks whether the current user namespace has all the IDs mapped.
func hasFullUsersMappings() (bool, error) {
content, err := os.ReadFile("/proc/self/uid_map")
if err != nil {
return false, err
}
// The kernel rejects attempts to create mappings where either starting
// point is (u32)-1: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/user_namespace.c?id=af3e9579ecfb#n1006 .
// So, if the uid_map contains 4294967295, the entire IDs space is available in the
// user namespace, so it is likely the initial user namespace.
return bytes.Contains(content, []byte("4294967295")), nil
}
// IsRootless tells us if we are running in rootless mode
func IsRootless() bool {
isRootlessOnce.Do(func() {
isRootless = getRootlessUID() != 0 || getenv(UsernsEnvName) != ""
if !isRootless {
hasCapSysAdmin, err := HasCapSysAdmin()
if err != nil {
logrus.Warnf("Failed to read CAP_SYS_ADMIN presence for the current process")
}
if err == nil && !hasCapSysAdmin {
isRootless = true
}
}
if !isRootless {
hasMappings, err := hasFullUsersMappings()
if err != nil {
logrus.Warnf("Failed to read current user namespace mappings")
}
if err == nil && !hasMappings {
isRootless = true
}
}
})
return isRootless
}

View File

@ -1,4 +1,4 @@
# This file is is the configuration file for all tools
# This file is the configuration file for all tools
# that use the containers/storage library. The storage.conf file
# overrides all other storage.conf files. Container engines using the
# container/storage library do not inherit fields from other storage.conf
@ -150,7 +150,7 @@ mountopt = "nodev"
# future. When "force_mask" is set the original permission mask is stored in
# the "user.containers.override_stat" xattr and the "mount_program" option must
# be specified. Mount programs like "/usr/bin/fuse-overlayfs" present the
# extended attribute permissions to processes within containers rather then the
# extended attribute permissions to processes within containers rather than the
# "force_mask" permissions.
#
# force_mask = ""

View File

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
@ -38,6 +37,13 @@ const (
removeNames
)
const (
volatileFlag = "Volatile"
mountLabelFlag = "MountLabel"
processLabelFlag = "ProcessLabel"
mountOptsFlag = "MountOpts"
)
var (
stores []*store
storesLock sync.Mutex
@ -410,7 +416,7 @@ type Store interface {
SetImageBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error
// ListLayerBigData retrieves a list of the (possibly large) chunks of
// named data associated with an layer.
// named data associated with a layer.
ListLayerBigData(id string) ([]string, error)
// LayerBigData retrieves a (possibly large) chunk of named data
@ -632,16 +638,17 @@ type store struct {
// If StoreOptions `options` haven't been fully populated, then DefaultStoreOptions are used.
//
// These defaults observe environment variables:
// * `STORAGE_DRIVER` for the name of the storage driver to attempt to use
// * `STORAGE_OPTS` for the string of options to pass to the driver
// - `STORAGE_DRIVER` for the name of the storage driver to attempt to use
// - `STORAGE_OPTS` for the string of options to pass to the driver
//
// Note that we do some of this work in a child process. The calling process's
// main() function needs to import our pkg/reexec package and should begin with
// something like this in order to allow us to properly start that child
// process:
// if reexec.Init() {
// return
// }
//
// if reexec.Init() {
// return
// }
func GetStore(options types.StoreOptions) (Store, error) {
defaultOpts, err := types.Options()
if err != nil {
@ -1399,11 +1406,10 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
if options.Flags == nil {
options.Flags = make(map[string]interface{})
}
plabel, _ := options.Flags["ProcessLabel"].(string)
mlabel, _ := options.Flags["MountLabel"].(string)
if (plabel == "" && mlabel != "") ||
(plabel != "" && mlabel == "") {
return nil, errors.New("processLabel and Mountlabel must either not be specified or both specified")
plabel, _ := options.Flags[processLabelFlag].(string)
mlabel, _ := options.Flags[mountLabelFlag].(string)
if (plabel == "" && mlabel != "") || (plabel != "" && mlabel == "") {
return nil, errors.New("ProcessLabel and Mountlabel must either not be specified or both specified")
}
if plabel == "" {
@ -1411,11 +1417,12 @@ func (s *store) CreateContainer(id string, names []string, image, layer, metadat
if err != nil {
return nil, err
}
options.Flags["ProcessLabel"] = processLabel
options.Flags["MountLabel"] = mountLabel
mlabel = mountLabel
options.Flags[processLabelFlag] = processLabel
options.Flags[mountLabelFlag] = mountLabel
}
clayer, err := rlstore.Create(layer, imageTopLayer, nil, options.Flags["MountLabel"].(string), options.StorageOpt, layerOptions, true)
clayer, err := rlstore.Create(layer, imageTopLayer, nil, mlabel, options.StorageOpt, layerOptions, true)
if err != nil {
return nil, err
}
@ -2790,8 +2797,10 @@ func (s *store) Mount(id, mountLabel string) (string, error) {
options.GidMaps = container.GIDMap
options.Options = container.MountOpts()
if !s.disableVolatile {
if v, found := container.Flags["Volatile"]; found {
options.Volatile = v.(bool)
if v, found := container.Flags[volatileFlag]; found {
if b, ok := v.(bool); ok {
options.Volatile = b
}
}
}
}
@ -3541,7 +3550,7 @@ func (s *store) FromContainerDirectory(id, file string) ([]byte, error) {
if err != nil {
return nil, err
}
return ioutil.ReadFile(filepath.Join(dir, file))
return os.ReadFile(filepath.Join(dir, file))
}
func (s *store) SetContainerRunDirectoryFile(id, file string, data []byte) error {
@ -3561,7 +3570,7 @@ func (s *store) FromContainerRunDirectory(id, file string) ([]byte, error) {
if err != nil {
return nil, err
}
return ioutil.ReadFile(filepath.Join(dir, file))
return os.ReadFile(filepath.Join(dir, file))
}
func (s *store) Shutdown(force bool) ([]string, error) {

View File

@ -38,17 +38,44 @@ var (
)
func loadDefaultStoreOptions() {
defaultStoreOptions.RunRoot = defaultRunRoot
defaultStoreOptions.GraphRoot = defaultGraphRoot
defaultStoreOptions.GraphDriverName = ""
setDefaults := func() {
// reload could set values to empty for run and graph root if config does not contains anything
if defaultStoreOptions.RunRoot == "" {
defaultStoreOptions.RunRoot = defaultRunRoot
}
if defaultStoreOptions.GraphRoot == "" {
defaultStoreOptions.GraphRoot = defaultGraphRoot
}
}
setDefaults()
if path, ok := os.LookupEnv(storageConfEnv); ok {
defaultOverrideConfigFile = path
if err := ReloadConfigurationFileIfNeeded(path, &defaultStoreOptions); err != nil {
loadDefaultStoreOptionsErr = err
return
}
} else if _, err := os.Stat(defaultOverrideConfigFile); err == nil {
setDefaults()
return
}
if path, ok := os.LookupEnv("XDG_CONFIG_HOME"); ok {
homeConfigFile := filepath.Join(path, "containers", "storage.conf")
if _, err := os.Stat(homeConfigFile); err == nil {
// user storage.conf in XDG_CONFIG_HOME if it exists
defaultOverrideConfigFile = homeConfigFile
} else {
if !os.IsNotExist(err) {
loadDefaultStoreOptionsErr = err
return
}
}
}
_, err := os.Stat(defaultOverrideConfigFile)
if err == nil {
// The DefaultConfigFile(rootless) function returns the path
// of the used storage.conf file, by returning defaultConfigFile
// If override exists containers/storage uses it by default.
@ -57,22 +84,18 @@ func loadDefaultStoreOptions() {
loadDefaultStoreOptionsErr = err
return
}
} else {
if !os.IsNotExist(err) {
logrus.Warningf("Attempting to use %s, %v", defaultConfigFile, err)
}
if err := ReloadConfigurationFileIfNeeded(defaultConfigFile, &defaultStoreOptions); err != nil && !errors.Is(err, os.ErrNotExist) {
loadDefaultStoreOptionsErr = err
return
}
setDefaults()
return
}
// reload could set values to empty for run and graph root if config does not contains anything
if defaultStoreOptions.RunRoot == "" {
defaultStoreOptions.RunRoot = defaultRunRoot
if !os.IsNotExist(err) {
logrus.Warningf("Attempting to use %s, %v", defaultConfigFile, err)
}
if defaultStoreOptions.GraphRoot == "" {
defaultStoreOptions.GraphRoot = defaultGraphRoot
if err := ReloadConfigurationFileIfNeeded(defaultConfigFile, &defaultStoreOptions); err != nil && !errors.Is(err, os.ErrNotExist) {
loadDefaultStoreOptionsErr = err
return
}
setDefaults()
}
// defaultStoreOptionsIsolated is an internal implementation detail of DefaultStoreOptions to allow testing.

View File

@ -3,7 +3,6 @@ package types
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
@ -75,7 +74,7 @@ func getRootlessRuntimeDirIsolated(env rootlessRuntimeDirEnvironment) (string, e
return runtimeDir, nil
}
initCommand, err := ioutil.ReadFile(env.getProcCommandFile())
initCommand, err := os.ReadFile(env.getProcCommandFile())
if err != nil || string(initCommand) == "systemd" {
runUserDir := env.getRunUserDir()
if isRootlessRuntimeDirOwner(runUserDir, env) {

View File

@ -226,7 +226,7 @@ func (s *store) getAutoUserNS(options *types.AutoUserNsOptions, image *Image) ([
return nil, nil, fmt.Errorf("cannot read mappings: %w", err)
}
// Look every container that is using a user namespace and store
// Look at every container that is using a user namespace and store
// the intervals that are already used.
containers, err := s.Containers()
if err != nil {

View File

@ -16,12 +16,12 @@ func GetRootlessRuntimeDir(rootlessUID int) (string, error) {
return types.GetRootlessRuntimeDir(rootlessUID)
}
// DefaultStoreOptionsAutoDetectUID returns the default storage ops for containers
// DefaultStoreOptionsAutoDetectUID returns the default storage options for containers
func DefaultStoreOptionsAutoDetectUID() (types.StoreOptions, error) {
return types.DefaultStoreOptionsAutoDetectUID()
}
// DefaultStoreOptions returns the default storage ops for containers
// DefaultStoreOptions returns the default storage options for containers
func DefaultStoreOptions(rootless bool, rootlessUID int) (types.StoreOptions, error) {
return types.DefaultStoreOptions(rootless, rootlessUID)
}

View File

@ -2,7 +2,6 @@ package units
import (
"fmt"
"regexp"
"strconv"
"strings"
)
@ -26,16 +25,17 @@ const (
PiB = 1024 * TiB
)
type unitMap map[string]int64
type unitMap map[byte]int64
var (
decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB}
binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB}
sizeRegex = regexp.MustCompile(`^(\d+(\.\d+)*) ?([kKmMgGtTpP])?[iI]?[bB]?$`)
decimalMap = unitMap{'k': KB, 'm': MB, 'g': GB, 't': TB, 'p': PB}
binaryMap = unitMap{'k': KiB, 'm': MiB, 'g': GiB, 't': TiB, 'p': PiB}
)
var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
var (
decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}
)
func getSizeAndUnit(size float64, base float64, _map []string) (float64, string) {
i := 0
@ -89,20 +89,66 @@ func RAMInBytes(size string) (int64, error) {
// Parses the human-readable size string into the amount it represents.
func parseSize(sizeStr string, uMap unitMap) (int64, error) {
matches := sizeRegex.FindStringSubmatch(sizeStr)
if len(matches) != 4 {
// TODO: rewrite to use strings.Cut if there's a space
// once Go < 1.18 is deprecated.
sep := strings.LastIndexAny(sizeStr, "01234567890. ")
if sep == -1 {
// There should be at least a digit.
return -1, fmt.Errorf("invalid size: '%s'", sizeStr)
}
var num, sfx string
if sizeStr[sep] != ' ' {
num = sizeStr[:sep+1]
sfx = sizeStr[sep+1:]
} else {
// Omit the space separator.
num = sizeStr[:sep]
sfx = sizeStr[sep+1:]
}
size, err := strconv.ParseFloat(matches[1], 64)
size, err := strconv.ParseFloat(num, 64)
if err != nil {
return -1, err
}
// Backward compatibility: reject negative sizes.
if size < 0 {
return -1, fmt.Errorf("invalid size: '%s'", sizeStr)
}
unitPrefix := strings.ToLower(matches[3])
if mul, ok := uMap[unitPrefix]; ok {
if len(sfx) == 0 {
return int64(size), nil
}
// Process the suffix.
if len(sfx) > 3 { // Too long.
goto badSuffix
}
sfx = strings.ToLower(sfx)
// Trivial case: b suffix.
if sfx[0] == 'b' {
if len(sfx) > 1 { // no extra characters allowed after b.
goto badSuffix
}
return int64(size), nil
}
// A suffix from the map.
if mul, ok := uMap[sfx[0]]; ok {
size *= float64(mul)
} else {
goto badSuffix
}
// The suffix may have extra "b" or "ib" (e.g. KiB or MB).
switch {
case len(sfx) == 2 && sfx[1] != 'b':
goto badSuffix
case len(sfx) == 3 && sfx[1:] != "ib":
goto badSuffix
}
return int64(size), nil
badSuffix:
return -1, fmt.Errorf("invalid suffix: '%s'", sfx)
}

View File

@ -1 +0,0 @@
.vagrant

View File

@ -1,43 +0,0 @@
language: go
dist: trusty
sudo: required
cache:
directories:
- $HOME/.ccache
- $HOME/zfs
branches:
only:
- master
env:
- rel=0.6.5.11
- rel=0.7.6
go:
- "1.10.x"
- master
before_install:
- export MAKEFLAGS=-j$(($(grep -c '^processor' /proc/cpuinfo) * 2 + 1))
- export PATH=/usr/lib/ccache:$PATH
- go get github.com/alecthomas/gometalinter
- gometalinter --install --update
- sudo apt-get update -y && sudo apt-get install -y libattr1-dev libblkid-dev linux-headers-$(uname -r) tree uuid-dev
- mkdir -p $HOME/zfs
- cd $HOME/zfs
- [[ -d spl-$rel.tar.gz ]] || curl -L https://github.com/zfsonlinux/zfs/releases/download/zfs-$rel/spl-$rel.tar.gz | tar xz
- [[ -d zfs-$rel.tar.gz ]] || curl -L https://github.com/zfsonlinux/zfs/releases/download/zfs-$rel/zfs-$rel.tar.gz | tar xz
- (cd spl-$rel && ./configure --prefix=/usr && make && sudo make install)
- (cd zfs-$rel && ./configure --prefix=/usr && make && sudo make install)
- sudo modprobe zfs
- cd $TRAVIS_BUILD_DIR
script:
- sudo -E $(which go) test -v ./...
- gometalinter --vendor --vendored-linters ./... || true
- gometalinter --errors --vendor --vendored-linters ./...
notifications:
email: false
irc: "chat.freenode.net#cerana"

View File

@ -1,34 +0,0 @@
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
config.ssh.forward_agent = true
config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/mistifyio/go-zfs", create: true
config.vm.provision "shell", inline: <<EOF
cat << END > /etc/profile.d/go.sh
export GOPATH=\\$HOME/go
export PATH=\\$GOPATH/bin:/usr/local/go/bin:\\$PATH
END
chown -R vagrant /home/vagrant/go
apt-get update
apt-get install -y software-properties-common curl
apt-add-repository --yes ppa:zfs-native/stable
apt-get update
apt-get install -y ubuntu-zfs
cd /home/vagrant
curl -z go1.3.3.linux-amd64.tar.gz -L -O https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz
tar -C /usr/local -zxf /home/vagrant/go1.3.3.linux-amd64.tar.gz
cat << END > /etc/sudoers.d/go
Defaults env_keep += "GOPATH"
END
EOF
end

View File

@ -1,17 +0,0 @@
// +build !solaris
package zfs
import (
"strings"
)
// List of ZFS properties to retrieve from zfs list command on a non-Solaris platform
var dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced", "written", "logicalused", "usedbydataset"}
var dsPropListOptions = strings.Join(dsPropList, ",")
// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform
var zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio", "fragmentation", "freeing", "leaked"}
var zpoolPropListOptions = strings.Join(zpoolPropList, ",")
var zpoolArgs = []string{"get", "-p", zpoolPropListOptions}

View File

@ -1,17 +0,0 @@
// +build solaris
package zfs
import (
"strings"
)
// List of ZFS properties to retrieve from zfs list command on a Solaris platform
var dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced"}
var dsPropListOptions = strings.Join(dsPropList, ",")
// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform
var zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio"}
var zpoolPropListOptions = strings.Join(zpoolPropList, ",")
var zpoolArgs = []string{"get", "-p", zpoolPropListOptions}

4
vendor/github.com/mistifyio/go-zfs/v3/.envrc generated vendored Normal file
View File

@ -0,0 +1,4 @@
has nix && use nix
dotenv_if_exists
PATH_add bin
path_add GOBIN bin

6
vendor/github.com/mistifyio/go-zfs/v3/.gitignore generated vendored Normal file
View File

@ -0,0 +1,6 @@
bin
go-zfs.test
.vagrant
# added by lint-install
out/

207
vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,207 @@
run:
# The default runtime timeout is 1m, which doesn't work well on Github Actions.
timeout: 4m
# NOTE: This file is populated by the lint-install tool. Local adjustments may be overwritten.
linters-settings:
cyclop:
# NOTE: This is a very high transitional threshold
max-complexity: 37
package-average: 34.0
skip-tests: true
gocognit:
# NOTE: This is a very high transitional threshold
min-complexity: 98
dupl:
threshold: 200
goconst:
min-len: 4
min-occurrences: 5
ignore-tests: true
gosec:
excludes:
- G107 # Potential HTTP request made with variable url
- G204 # Subprocess launched with function call as argument or cmd arguments
- G404 # Use of weak random number generator (math/rand instead of crypto/rand
errorlint:
# these are still common in Go: for instance, exit errors.
asserts: false
exhaustive:
default-signifies-exhaustive: true
nestif:
min-complexity: 8
nolintlint:
require-explanation: true
allow-unused: false
require-specific: true
revive:
ignore-generated-header: true
severity: warning
rules:
- name: atomic
- name: blank-imports
- name: bool-literal-in-expr
- name: confusing-naming
- name: constant-logical-expr
- name: context-as-argument
- name: context-keys-type
- name: deep-exit
- name: defer
- name: range-val-in-closure
- name: range-val-address
- name: dot-imports
- name: error-naming
- name: error-return
- name: error-strings
- name: errorf
- name: exported
- name: identical-branches
- name: if-return
- name: import-shadowing
- name: increment-decrement
- name: indent-error-flow
- name: indent-error-flow
- name: package-comments
- name: range
- name: receiver-naming
- name: redefines-builtin-id
- name: superfluous-else
- name: struct-tag
- name: time-naming
- name: unexported-naming
- name: unexported-return
- name: unnecessary-stmt
- name: unreachable-code
- name: unused-parameter
- name: var-declaration
- name: var-naming
- name: unconditional-recursion
- name: waitgroup-by-value
staticcheck:
go: "1.16"
unused:
go: "1.16"
output:
sort-results: true
linters:
disable-all: true
enable:
- asciicheck
- bodyclose
- cyclop
- deadcode
- dogsled
- dupl
- durationcheck
- errcheck
- errname
- errorlint
- exhaustive
- exportloopref
- forcetypeassert
- gocognit
- goconst
- gocritic
- godot
- gofmt
- gofumpt
- gosec
- goheader
- goimports
- goprintffuncname
- gosimple
- govet
- ifshort
- importas
- ineffassign
- makezero
- misspell
- nakedret
- nestif
- nilerr
- noctx
- nolintlint
- predeclared
# disabling for the initial iteration of the linting tool
# - promlinter
- revive
- rowserrcheck
- sqlclosecheck
- staticcheck
- structcheck
- stylecheck
- thelper
- tparallel
- typecheck
- unconvert
- unparam
- unused
- varcheck
- wastedassign
- whitespace
# Disabled linters, due to being misaligned with Go practices
# - exhaustivestruct
# - gochecknoglobals
# - gochecknoinits
# - goconst
# - godox
# - goerr113
# - gomnd
# - lll
# - nlreturn
# - testpackage
# - wsl
# Disabled linters, due to not being relevant to our code base:
# - maligned
# - prealloc "For most programs usage of prealloc will be a premature optimization."
# Disabled linters due to bad error messages or bugs
# - tagliatelle
issues:
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- path: _test\.go
linters:
- dupl
- errcheck
- forcetypeassert
- gocyclo
- gosec
- noctx
- path: .*cmd.*
linters:
- noctx
- path: main\.go
linters:
- noctx
- path: .*cmd.*
text: "deep-exit"
- path: main\.go
text: "deep-exit"
# This check is of questionable value
- linters:
- tparallel
text: "call t.Parallel on the top level as well as its subtests"
# Don't hide lint issues just because there are many of them
max-same-issues: 0
max-issues-per-linter: 0

16
vendor/github.com/mistifyio/go-zfs/v3/.yamllint generated vendored Normal file
View File

@ -0,0 +1,16 @@
---
extends: default
rules:
braces:
max-spaces-inside: 1
brackets:
max-spaces-inside: 1
comments: disable
comments-indentation: disable
document-start: disable
line-length:
level: warning
max: 160
allow-non-breakable-inline-mappings: true
truthy: disable

250
vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,250 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
This change log follows the advice of [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog).
## [Unreleased]
## [3.0.0] - 2022-03-30
### Added
- Rename, Mount and Unmount methods
- Parse more fields into Zpool type:
- dedupratio
- fragmentation
- freeing
- leaked
- readonly
- Parse more fields into Dataset type:
- referenced
- Incremental Send
- Parse numbers in exact format
- Support for Solaris (non-blockint, best-effort status)
- Debug logging for command invocation
- Use GitHub Actions for CI
- Nix shell for dev env reproducibility
- Direnv file for ease of dev
- Formatting/lint checks (enforced by CI)
- Go Module
- FreeBSD based vagrant machine
### Changed
- Temporarily adjust TestDiff expected strings depending on ZFS version
- Use one `zfs list`/`zpool list` call instead of many `zfs get`/`zpool get`
- ZFS docs links now point to OpenZFS pages
- Ubuntu vagrant box changed to generic/ubuntu2004
### Fixed
- `GetProperty` returning `VALUE` instead of the actual value
### Shortlog
Amit Krishnan (1):
Issue #39 and Issue #40 - Enable Solaris support for go-zfs Switch from zfs/zpool get to zfs/zpool list for better performance Signed-off-by: Amit Krishnan <krish.amit@gmail.com>
Anand Patil (3):
Added Rename
Small fix to rename.
Added mount and umount methods
Brian Akins (1):
Add 'referenced' to zfs properties
Brian Bickerton (3):
Add debug logging before and after running external zfs command
Don't export the default no-op logger
Update uuid package repo url
Dmitry Teselkin (1):
Issue #52 - fix parseLine for fragmentation field
Edward Betts (1):
correct spelling mistake
Justin Cormack (1):
Switch to google/uuid which is the maintained version of pborman/uuid
Manuel Mendez (40):
rename Umount -> Unmount to follow zfs command name
add missing Unmount/Mount docs
always allocate largest Mount slice
add travis config
travis: update to go 1.7
travis: get go deps first
test: add nok helper to verify an error occurred
test: add test for Dataset.GetProperty
ci: swap #cerana on freenode for slack
ci: install new deps for 0.7 relases
ci: bump zol versions
ci: bump go versions
ci: use better gometalinter invocations
ci: add ccache
ci: set env earlier in before_install
fix test nok error printing
test: restructure TestDiff to deal with different order of changes
test: better unicode path handling in TestDiff
travis: bump zfs and go versions
cache zfs artifacts
Add nix-shell and direnv goodness
prettierify all the files
Add go based tools
Add Makefile and rules.mk files
gofumptize the code base
Use tinkerbell/lint-install to setup linters
make golangci-lint happy
Update CONTRIBUTING.md with make based approach
Add GitHub Actions
Drop Travis CI
One sentence per line
Update documentation links to openzfs-docs pages
Format Vagrantfile using rufo
Add go-zfs.test to .gitignore
test: Avoid reptitive/duplicate error logging and quitting
test: Use t.Logf instead of fmt.Printf
test: Better cleanup and error handling in zpoolTest
test: Do not mark TestDatasets as a t.Helper.
test: Change zpoolTest to a pure helper that returns a clean up function
test: Move helpers to a different file
vagrant: Add set -euxo pipefail to provision script
vagrant: Update to generic/ubuntu2004
vagrant: Minor fixes to Vagrantfile
vagrant: Update to go 1.17.8
vagrant: Run go tests as part of provision script
vagrant: Indent heredoc script
vagrant: Add freebsd machine
Matt Layher (1):
Parse more fields into Zpool type
Michael Crosby (1):
Add incremental send
Rikard Gynnerstedt (1):
remove command name from joined args
Sebastiaan van Stijn (1):
Add go.mod and rename to github.com/mistifyio/go-zfs/v3 (v3.0.0)
mikudeko (1):
Fix GetProperty always returning 'VALUE'
## [2.1.1] - 2015-05-29
### Fixed
- Ignoring first pool listed
- Incorrect `zfs get` argument ordering
### Shortlog
Alexey Guskov (1):
zfs command uses different order of arguments on freebsd
Brian Akins (4):
test that ListZpools returns expected zpool
test error first
test error first
fix test to check correct return value
James Cunningham (1):
Fix Truncating First Zpool
Pat Norton (2):
Added Use of Go Tools
Update CONTRIBUTING.md
## [2.1.0] - 2014-12-08
### Added
- Parse hardlink modification count returned from `zfs diff`
### Fixed
- Continuing instead of erroring when rolling back a non-snapshot
### Shortlog
Brian Akins (2):
need to return the error here
use named struct fields
Jörg Thalheim (1):
zfs diff handle hardlinks modification now
## [2.0.0] - 2014-12-02
### Added
- Flags for Destroy:
- DESTROY_DEFAULT
- DESTROY_DEFER_DELETION (`zfs destroy ... -d`)
- DESTROY_FORCE (`zfs destroy ... -f`)
- DESTROY_RECURSIVE_CLONES (`zfs destroy ... -R`)
- DESTROY_RECURSIVE (`zfs destroy ... -r`)
- etc
- Diff method (`zfs diff`)
- LogicalUsed and Origin properties to Dataset
- Type constants for Dataset
- State constants for Zpool
- Logger interface
- Improve documentation
### Shortlog
Brian Akins (8):
remove reflection
style change for switches
need to check for error
keep in scope
go 1.3.3
golint cleanup
Just test if logical used is greater than 0, as this appears to be implementation specific
add docs to satisfy golint
Jörg Thalheim (8):
Add deferred flag to zfs.Destroy()
add Logicalused property
Add Origin property
gofmt
Add zfs.Diff
Add Logger
add recursive destroy with clones
use CamelCase-style constants
Matt Layher (4):
Improve documentation, document common ZFS operations, provide more references
Add zpool state constants, for easier health checking
Add dataset type constants, for easier type checking
Fix string split in command.Run(), use strings.Fields() instead of strings.Split()
## [1.0.0] - 2014-11-12
### Shortlog
Brian Akins (7):
add godoc badge
Add example
add information about zpool to struct and parser
Add Quota
add Children call
add Children call
fix snapshot tests
Brian Bickerton (3):
MIST-150 Change Snapshot second paramater from properties map[string][string] to recursive bool
MIST-150 Add Rollback method and related tests
MIST-160 Add SendSnapshot streaming method and tests
Matt Layher (1):
Add Error struct type and tests, enabling easier error return checking
[3.0.0]: https://github.com/mistifyio/go-zfs/compare/v2.1.1...v3.0.0
[2.1.1]: https://github.com/mistifyio/go-zfs/compare/v2.1.0...v2.1.1
[2.1.0]: https://github.com/mistifyio/go-zfs/compare/v2.0.0...v2.1.0
[2.0.0]: https://github.com/mistifyio/go-zfs/compare/v1.0.0...v2.0.0
[1.0.0]: https://github.com/mistifyio/go-zfs/compare/v0.0.0...v1.0.0

View File

@ -1,20 +1,23 @@
## How to Contribute ##
## How to Contribute
We always welcome contributions to help make `go-zfs` better. Please take a moment to read this document if you would like to contribute.
We always welcome contributions to help make `go-zfs` better.
Please take a moment to read this document if you would like to contribute.
### Reporting issues ###
### Reporting issues
We use [Github issues](https://github.com/mistifyio/go-zfs/issues) to track bug reports, feature requests, and submitting pull requests.
If you find a bug:
* Use the GitHub issue search to check whether the bug has already been reported.
* If the issue has been fixed, try to reproduce the issue using the latest `master` branch of the repository.
* If the issue still reproduces or has not yet been reported, try to isolate the problem before opening an issue, if possible. Also provide the steps taken to reproduce the bug.
- Use the GitHub issue search to check whether the bug has already been reported.
- If the issue has been fixed, try to reproduce the issue using the latest `master` branch of the repository.
- If the issue still reproduces or has not yet been reported, try to isolate the problem before opening an issue, if possible. Also provide the steps taken to reproduce the bug.
### Pull requests ###
### Pull requests
We welcome bug fixes, improvements, and new features. Before embarking on making significant changes, please open an issue and ask first so that you do not risk duplicating efforts or spending time working on something that may be out of scope. For minor items, just open a pull request.
We welcome bug fixes, improvements, and new features.
Before embarking on making significant changes, please open an issue and ask first so that you do not risk duplicating efforts or spending time working on something that may be out of scope.
For minor items, just open a pull request.
[Fork the project](https://help.github.com/articles/fork-a-repo), clone your fork, and add the upstream to your remote:
@ -28,11 +31,13 @@ If you need to pull new changes committed upstream:
$ git fetch upstream
$ git merge upstream/master
Don' work directly on master as this makes it harder to merge later. Create a feature branch for your fix or new feature:
Don' work directly on master as this makes it harder to merge later.
Create a feature branch for your fix or new feature:
$ git checkout -b <feature-branch-name>
Please try to commit your changes in logical chunks. Ideally, you should include the issue number in the commit message.
Please try to commit your changes in logical chunks.
Ideally, you should include the issue number in the commit message.
$ git commit -m "Issue #<issue-number> - <commit-message>"
@ -40,21 +45,20 @@ Push your feature branch to your fork.
$ git push origin <feature-branch-name>
[Open a Pull Request](https://help.github.com/articles/using-pull-requests) against the upstream master branch. Please give your pull request a clear title and description and note which issue(s) your pull request fixes.
[Open a Pull Request](https://help.github.com/articles/using-pull-requests) against the upstream master branch.
Please give your pull request a clear title and description and note which issue(s) your pull request fixes.
* All Go code should be formatted using [gofmt](http://golang.org/cmd/gofmt/).
* Every exported function should have [documentation](http://blog.golang.org/godoc-documenting-go-code) and corresponding [tests](http://golang.org/doc/code.html#Testing).
- All linters should be happy (can be run with `make verify`).
- Every exported function should have [documentation](http://blog.golang.org/godoc-documenting-go-code) and corresponding [tests](http://golang.org/doc/code.html#Testing).
**Important:** By submitting a patch, you agree to allow the project owners to license your work under the [Apache 2.0 License](./LICENSE).
### Go Tools ###
For consistency and to catch minor issues for all of go code, please run the following:
* goimports
* go vet
* golint
* errcheck
### Go Tools
For consistency and to catch minor issues for all of go code, please run `make verify`.
Many editors can execute the above on save.
----
---
Guidelines based on http://azkaban.github.io/contributing.html

19
vendor/github.com/mistifyio/go-zfs/v3/Makefile generated vendored Normal file
View File

@ -0,0 +1,19 @@
help: ## Print this help
@grep --no-filename -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sed 's/:.*## /·/' | sort | column -t -W 2 -s '·' -c $(shell tput cols)
all: test ## Run tests
-include rules.mk
-include lint.mk
test: ## Run tests
go test ./...
verify: gofumpt prettier lint ## Verify code style, is lint free, freshness ...
git diff | (! grep .)
fix: gofumpt-fix prettier-fix ## Fix code formatting errors
tools: ${toolsBins} ## Build Go based build tools
.PHONY: all help test tools verify

View File

@ -1,12 +1,12 @@
# Go Wrapper for ZFS #
# Go Wrapper for ZFS
Simple wrappers for ZFS command line tools.
[![GoDoc](https://godoc.org/github.com/mistifyio/go-zfs?status.svg)](https://godoc.org/github.com/mistifyio/go-zfs)
## Requirements ##
## Requirements
You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS:
You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS:
sudo apt-get install python-software-properties
sudo apt-add-repository ppa:zfs-native/stable
@ -17,13 +17,13 @@ Developed using Go 1.3, but currently there isn't anything 1.3 specific. Don't u
Generally you need root privileges to use anything zfs related.
## Status ##
## Status
This has been only been tested on Ubuntu 14.04
In the future, we hope to work directly with libzfs.
# Hacking #
# Hacking
The tests have decent examples for most functions.
@ -48,7 +48,6 @@ err := f.Destroy()
```
# Contributing #
# Contributing
See the [contributing guidelines](./CONTRIBUTING.md)

33
vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile generated vendored Normal file
View File

@ -0,0 +1,33 @@
GOVERSION = "1.17.8"
Vagrant.configure("2") do |config|
config.vm.define "ubuntu" do |ubuntu|
ubuntu.vm.box = "generic/ubuntu2004"
end
config.vm.define "freebsd" do |freebsd|
freebsd.vm.box = "generic/freebsd13"
end
config.ssh.forward_agent = true
config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/mistifyio/go-zfs", create: true
config.vm.provision "shell", inline: <<-EOF
set -euxo pipefail
os=$(uname -s|tr '[A-Z]' '[a-z]')
case $os in
linux) apt-get update -y && apt-get install -y --no-install-recommends gcc libc-dev zfsutils-linux ;;
esac
cd /tmp
curl -fLO --retry-max-time 30 --retry 10 https://go.dev/dl/go#{GOVERSION}.$os-amd64.tar.gz
tar -C /usr/local -zxf go#{GOVERSION}.$os-amd64.tar.gz
ln -nsf /usr/local/go/bin/go /usr/local/bin/go
rm -rf go*.tar.gz
chown -R vagrant:vagrant /home/vagrant/go
cd /home/vagrant/go/src/github.com/mistifyio/go-zfs
go test -c
sudo ./go-zfs.test -test.v
CGO_ENABLED=0 go test -c
sudo ./go-zfs.test -test.v
EOF
end

75
vendor/github.com/mistifyio/go-zfs/v3/lint.mk generated vendored Normal file
View File

@ -0,0 +1,75 @@
# BEGIN: lint-install -makefile lint.mk .
# http://github.com/tinkerbell/lint-install
.PHONY: lint
lint: _lint
LINT_ARCH := $(shell uname -m)
LINT_OS := $(shell uname)
LINT_OS_LOWER := $(shell echo $(LINT_OS) | tr '[:upper:]' '[:lower:]')
LINT_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
# shellcheck and hadolint lack arm64 native binaries: rely on x86-64 emulation
ifeq ($(LINT_OS),Darwin)
ifeq ($(LINT_ARCH),arm64)
LINT_ARCH=x86_64
endif
endif
LINTERS :=
FIXERS :=
SHELLCHECK_VERSION ?= v0.8.0
SHELLCHECK_BIN := out/linters/shellcheck-$(SHELLCHECK_VERSION)-$(LINT_ARCH)
$(SHELLCHECK_BIN):
mkdir -p out/linters
rm -rf out/linters/shellcheck-*
curl -sSfL https://github.com/koalaman/shellcheck/releases/download/$(SHELLCHECK_VERSION)/shellcheck-$(SHELLCHECK_VERSION).$(LINT_OS_LOWER).$(LINT_ARCH).tar.xz | tar -C out/linters -xJf -
mv out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck $@
rm -rf out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck
LINTERS += shellcheck-lint
shellcheck-lint: $(SHELLCHECK_BIN)
$(SHELLCHECK_BIN) $(shell find . -name "*.sh")
FIXERS += shellcheck-fix
shellcheck-fix: $(SHELLCHECK_BIN)
$(SHELLCHECK_BIN) $(shell find . -name "*.sh") -f diff | { read -t 1 line || exit 0; { echo "$$line" && cat; } | git apply -p2; }
GOLANGCI_LINT_CONFIG := $(LINT_ROOT)/.golangci.yml
GOLANGCI_LINT_VERSION ?= v1.43.0
GOLANGCI_LINT_BIN := out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH)
$(GOLANGCI_LINT_BIN):
mkdir -p out/linters
rm -rf out/linters/golangci-lint-*
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b out/linters $(GOLANGCI_LINT_VERSION)
mv out/linters/golangci-lint $@
LINTERS += golangci-lint-lint
golangci-lint-lint: $(GOLANGCI_LINT_BIN)
find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" \;
FIXERS += golangci-lint-fix
golangci-lint-fix: $(GOLANGCI_LINT_BIN)
find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" --fix \;
YAMLLINT_VERSION ?= 1.26.3
YAMLLINT_ROOT := out/linters/yamllint-$(YAMLLINT_VERSION)
YAMLLINT_BIN := $(YAMLLINT_ROOT)/dist/bin/yamllint
$(YAMLLINT_BIN):
mkdir -p out/linters
rm -rf out/linters/yamllint-*
curl -sSfL https://github.com/adrienverge/yamllint/archive/refs/tags/v$(YAMLLINT_VERSION).tar.gz | tar -C out/linters -zxf -
cd $(YAMLLINT_ROOT) && pip3 install --target dist .
LINTERS += yamllint-lint
yamllint-lint: $(YAMLLINT_BIN)
PYTHONPATH=$(YAMLLINT_ROOT)/dist $(YAMLLINT_ROOT)/dist/bin/yamllint .
.PHONY: _lint $(LINTERS)
_lint: $(LINTERS)
.PHONY: fix $(FIXERS)
fix: $(FIXERS)
# END: lint-install -makefile lint.mk .

49
vendor/github.com/mistifyio/go-zfs/v3/rules.mk generated vendored Normal file
View File

@ -0,0 +1,49 @@
# Only use the recipes defined in these makefiles
MAKEFLAGS += --no-builtin-rules
.SUFFIXES:
# Delete target files if there's an error
# This avoids a failure to then skip building on next run if the output is created by shell redirection for example
# Not really necessary for now, but just good to have already if it becomes necessary later.
.DELETE_ON_ERROR:
# Treat the whole recipe as a one shell script/invocation instead of one-per-line
.ONESHELL:
# Use bash instead of plain sh
SHELL := bash
.SHELLFLAGS := -o pipefail -euc
version := $(shell git rev-parse --short HEAD)
tag := $(shell git tag --points-at HEAD)
ifneq (,$(tag))
version := $(tag)-$(version)
endif
LDFLAGS := -ldflags "-X main.version=$(version)"
export CGO_ENABLED := 0
ifeq ($(origin GOBIN), undefined)
GOBIN := ${PWD}/bin
export GOBIN
PATH := ${GOBIN}:${PATH}
export PATH
endif
toolsBins := $(addprefix bin/,$(notdir $(shell grep '^\s*_' tooling/tools.go | awk -F'"' '{print $$2}')))
# installs cli tools defined in tools.go
$(toolsBins): tooling/go.mod tooling/go.sum tooling/tools.go
$(toolsBins): CMD=$(shell awk -F'"' '/$(@F)"/ {print $$2}' tooling/tools.go)
$(toolsBins):
cd tooling && go install $(CMD)
.PHONY: gofumpt
gofumpt: bin/gofumpt
gofumpt -s -d .
gofumpt-fix: bin/gofumpt
gofumpt -s -w .
.PHONY: prettier prettier-fix
prettier:
prettier --list-different --ignore-path .gitignore .
prettier-fix:
prettier --write --ignore-path .gitignore .

26
vendor/github.com/mistifyio/go-zfs/v3/shell.nix generated vendored Normal file
View File

@ -0,0 +1,26 @@
let _pkgs = import <nixpkgs> { };
in { pkgs ? import (_pkgs.fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs";
#branch@date: 21.11@2022-02-13
rev = "560ad8a2f89586ab1a14290f128ad6a393046065";
sha256 = "0s0dv1clfpjyzy4p6ywxvzmwx9ddbr2yl77jf1wqdbr0x1206hb8";
}) { } }:
with pkgs;
mkShell {
buildInputs = [
git
gnumake
gnused
go
nixfmt
nodePackages.prettier
python3Packages.pip
python3Packages.setuptools
rufo
shfmt
vagrant
];
}

Some files were not shown because too many files have changed in this diff Show More