Skip to content

Commit 96e3e92

Browse files
authored
Merge pull request #2 from truenas/se/add-truenas-iscsi
TrueNAS Incus Driver - iSCSI
2 parents 82e972d + 55667bb commit 96e3e92

File tree

485 files changed

+65377
-43987
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

485 files changed

+65377
-43987
lines changed

.devcontainer/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ RUN go install -v github.com/google/go-licenses@latest && \
9595
GOTOOLCHAIN="" go install -v golang.org/x/tools/gopls@latest && \
9696
go install -v github.com/go-delve/delve/cmd/dlv@latest && \
9797
go install -v golang.org/x/tools/cmd/goimports@latest && \
98+
go install -v golang.org/x/vuln/cmd/govulncheck@latest && \
9899
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
99100

100101
# Make dependencies

.github/workflows/tests.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,20 +486,36 @@ jobs:
486486
run: |
487487
mkdir bin
488488
489-
- name: Build static x86_64 incus
489+
- name: Build static incus (x86_64)
490490
env:
491491
CGO_ENABLED: 0
492492
GOARCH: amd64
493493
run: |
494494
go build -o bin/incus.x86_64 ./cmd/incus
495495
496-
- name: Build static aarch64 incus
496+
- name: Build static incus (aarch64)
497497
env:
498498
CGO_ENABLED: 0
499499
GOARCH: arm64
500500
run: |
501501
go build -o bin/incus.aarch64 ./cmd/incus
502502
503+
- name: Build static incus-agent (x86_64)
504+
if: runner.os == 'Linux' || runner.os == 'Windows'
505+
env:
506+
CGO_ENABLED: 0
507+
GOARCH: amd64
508+
run: |
509+
go build -o bin/incus-agent.x86_64 ./cmd/incus-agent
510+
511+
- name: Build static incus-agent (aarch64)
512+
if: runner.os == 'Linux' || runner.os == 'Windows'
513+
env:
514+
CGO_ENABLED: 0
515+
GOARCH: arm64
516+
run: |
517+
go build -o bin/incus-agent.aarch64 ./cmd/incus-agent
518+
503519
- name: Build static incus-migrate
504520
if: runner.os == 'Linux'
505521
env:

CONTRIBUTING.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ By default, any contribution to this project is made under the Apache
1818
The author of a change remains the copyright holder of their code
1919
(no copyright assignment).
2020

21+
## No Large Language Models (LLMs) or similar AI tools
22+
23+
All contributions to this project are expected to be done by human
24+
beings or through standard predictable tooling (e.g. scripts, formatters, ...).
25+
26+
We expect all contributors to be able to reason about the code that they
27+
contribute and explain why they're taking a particular approach.
28+
29+
LLMs and similar predictive tools have the annoying tendency of
30+
producing large amount of low quality code with subtle issues which end
31+
up taking the maintainers more time to debug than it would have taken to
32+
write the code by hand in the first place.
33+
34+
Any attempt at hiding the use of LLMs or similar tools in Incus contributions
35+
will result in a revert of the affected changes and a ban from the project.
36+
2137
## Pull requests
2238

2339
Changes to this project should be proposed as pull requests on GitHub

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ ifneq "$(INCUS_OFFLINE)" ""
9494
exit 1
9595
endif
9696
$(GO) get -t -v -u ./...
97+
$(GO) get github.com/go-jose/go-jose/v4@v4.0.5
9798
$(GO) mod tidy --go=1.23.7
9899
$(GO) get toolchain@none
99100

@@ -296,6 +297,9 @@ static-analysis:
296297
ifeq ($(shell command -v go-licenses),)
297298
(cd / ; $(GO) install -v -x github.com/google/go-licenses@latest)
298299
endif
300+
ifeq ($(shell command -v govulncheck),)
301+
go install golang.org/x/vuln/cmd/govulncheck@latest
302+
endif
299303
ifeq ($(shell command -v golangci-lint),)
300304
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$($(GO) env GOPATH)/bin
301305
endif

client/incus.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ func incusParseResponse(resp *http.Response) (*api.Response, string, error) {
246246

247247
// Handle errors
248248
if response.Type == api.ErrorResponse {
249-
return &response, "", api.StatusErrorf(resp.StatusCode, response.Error)
249+
return &response, "", api.StatusErrorf(resp.StatusCode, "%v", response.Error)
250250
}
251251

252252
return &response, etag, nil
@@ -300,7 +300,7 @@ func (r *ProtocolIncus) rawQuery(method string, url string, data any, ETag strin
300300
req.Header.Set("Content-Type", "application/json")
301301

302302
// Log the data
303-
logger.Debugf(logger.Pretty(data))
303+
logger.Debugf("%s", logger.Pretty(data))
304304
}
305305
} else {
306306
// No data to be sent along with the request
@@ -386,7 +386,7 @@ func (r *ProtocolIncus) queryStruct(method string, path string, data any, ETag s
386386

387387
// Log the data
388388
logger.Debugf("Got response struct from Incus")
389-
logger.Debugf(logger.Pretty(target))
389+
logger.Debugf("%s", logger.Pretty(target))
390390

391391
return etag, nil
392392
}
@@ -436,7 +436,7 @@ func (r *ProtocolIncus) queryOperation(method string, path string, data any, ETa
436436

437437
// Log the data
438438
logger.Debugf("Got operation from Incus")
439-
logger.Debugf(logger.Pretty(op.Operation))
439+
logger.Debugf("%s", logger.Pretty(op.Operation))
440440

441441
return &op, etag, nil
442442
}

client/incus_certificates.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ func (r *ProtocolIncus) GetCertificates() ([]api.Certificate, error) {
3636
return certificates, nil
3737
}
3838

39+
// GetCertificatesWithFilter returns a filtered list of certificates.
40+
func (r *ProtocolIncus) GetCertificatesWithFilter(filters []string) ([]api.Certificate, error) {
41+
certificates := []api.Certificate{}
42+
43+
v := url.Values{}
44+
v.Set("recursion", "1")
45+
v.Set("filter", parseFilters(filters))
46+
47+
// Fetch the raw value
48+
_, err := r.queryStruct("GET", fmt.Sprintf("/certificates?%s", v.Encode()), nil, "", &certificates)
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
return certificates, nil
54+
}
55+
3956
// GetCertificate returns the certificate entry for the provided fingerprint.
4057
func (r *ProtocolIncus) GetCertificate(fingerprint string) (*api.Certificate, string, error) {
4158
certificate := api.Certificate{}

client/incus_images.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
279279
}
280280

281281
// Hashing
282-
hashSHA256 := sha256.New()
282+
hash256 := sha256.New()
283283

284284
// Deal with split images
285285
if ctype == "multipart/form-data" {
@@ -300,7 +300,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
300300
return nil, fmt.Errorf("Invalid multipart image")
301301
}
302302

303-
size, err := io.Copy(io.MultiWriter(req.MetaFile, hashSHA256), part)
303+
size, err := io.Copy(io.MultiWriter(req.MetaFile, hash256), part)
304304
if err != nil {
305305
return nil, err
306306
}
@@ -318,7 +318,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
318318
return nil, fmt.Errorf("Invalid multipart image")
319319
}
320320

321-
size, err = io.Copy(io.MultiWriter(req.RootfsFile, hashSHA256), part)
321+
size, err = io.Copy(io.MultiWriter(req.RootfsFile, hash256), part)
322322
if err != nil {
323323
return nil, err
324324
}
@@ -327,7 +327,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
327327
resp.RootfsName = part.FileName()
328328

329329
// Check the hash
330-
hash := fmt.Sprintf("%x", hashSHA256.Sum(nil))
330+
hash := fmt.Sprintf("%x", hash256.Sum(nil))
331331
if imageType != "oci" && !strings.HasPrefix(hash, fingerprint) {
332332
return nil, fmt.Errorf("Image fingerprint doesn't match. Got %s expected %s", hash, fingerprint)
333333
}
@@ -346,7 +346,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
346346
return nil, fmt.Errorf("No filename in Content-Disposition header")
347347
}
348348

349-
size, err := io.Copy(io.MultiWriter(req.MetaFile, hashSHA256), body)
349+
size, err := io.Copy(io.MultiWriter(req.MetaFile, hash256), body)
350350
if err != nil {
351351
return nil, err
352352
}
@@ -355,7 +355,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
355355
resp.MetaName = filename
356356

357357
// Check the hash
358-
hash := fmt.Sprintf("%x", hashSHA256.Sum(nil))
358+
hash := fmt.Sprintf("%x", hash256.Sum(nil))
359359
if imageType != "oci" && !strings.HasPrefix(hash, fingerprint) {
360360
return nil, fmt.Errorf("Image fingerprint doesn't match. Got %s expected %s", hash, fingerprint)
361361
}
@@ -462,7 +462,6 @@ func (r *ProtocolIncus) CreateImage(image api.ImagesPost, args *ImageCreateArgs)
462462
}
463463

464464
// Prepare the body
465-
var ioErr error
466465
var body io.Reader
467466
var contentType string
468467
if args.RootfsFile == nil {
@@ -610,10 +609,6 @@ func (r *ProtocolIncus) CreateImage(image api.ImagesPost, args *ImageCreateArgs)
610609

611610
defer func() { _ = resp.Body.Close() }()
612611

613-
if ioErr != nil {
614-
return nil, err
615-
}
616-
617612
// Handle errors
618613
response, _, err := incusParseResponse(resp)
619614
if err != nil {
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package incus
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
7+
"github.com/lxc/incus/v6/shared/api"
8+
)
9+
10+
// GetNetworkAddressSetNames returns a list of network address set names.
11+
func (r *ProtocolIncus) GetNetworkAddressSetNames() ([]string, error) {
12+
if !r.HasExtension("network_address_set") {
13+
return nil, fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
14+
}
15+
16+
// Fetch the raw URL values.
17+
urls := []string{}
18+
baseURL := "/network-address-sets"
19+
_, err := r.queryStruct("GET", baseURL, nil, "", &urls)
20+
if err != nil {
21+
return nil, err
22+
}
23+
24+
// Parse it.
25+
return urlsToResourceNames(baseURL, urls...)
26+
}
27+
28+
// GetNetworkAddressSets returns a list of network address set structs.
29+
func (r *ProtocolIncus) GetNetworkAddressSets() ([]api.NetworkAddressSet, error) {
30+
if !r.HasExtension("network_address_set") {
31+
return nil, fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
32+
}
33+
34+
addressSets := []api.NetworkAddressSet{}
35+
36+
// Fetch the raw value.
37+
_, err := r.queryStruct("GET", "/network-address-sets?recursion=1", nil, "", &addressSets)
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
return addressSets, nil
43+
}
44+
45+
// GetNetworkAddressSetsAllProjects returns a list of network address set structs across all projects.
46+
func (r *ProtocolIncus) GetNetworkAddressSetsAllProjects() ([]api.NetworkAddressSet, error) {
47+
if !r.HasExtension("network_address_set") {
48+
return nil, fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
49+
}
50+
51+
addressSets := []api.NetworkAddressSet{}
52+
_, err := r.queryStruct("GET", "/network-address-sets?recursion=1&all-projects=true", nil, "", &addressSets)
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
return addressSets, nil
58+
}
59+
60+
// GetNetworkAddressSet returns a network address set entry for the provided name.
61+
func (r *ProtocolIncus) GetNetworkAddressSet(name string) (*api.NetworkAddressSet, string, error) {
62+
if !r.HasExtension("network_address_set") {
63+
return nil, "", fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
64+
}
65+
66+
addrSet := api.NetworkAddressSet{}
67+
68+
// Fetch the raw value.
69+
etag, err := r.queryStruct("GET", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), nil, "", &addrSet)
70+
if err != nil {
71+
return nil, "", err
72+
}
73+
74+
return &addrSet, etag, nil
75+
}
76+
77+
// CreateNetworkAddressSet defines a new network address set using the provided struct.
78+
func (r *ProtocolIncus) CreateNetworkAddressSet(as api.NetworkAddressSetsPost) error {
79+
if !r.HasExtension("network_address_set") {
80+
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
81+
}
82+
83+
// Send the request.
84+
_, _, err := r.query("POST", "/network-address-sets", as, "")
85+
if err != nil {
86+
return err
87+
}
88+
89+
return nil
90+
}
91+
92+
// UpdateNetworkAddressSet updates the network address set to match the provided struct.
93+
func (r *ProtocolIncus) UpdateNetworkAddressSet(name string, as api.NetworkAddressSetPut, ETag string) error {
94+
if !r.HasExtension("network_address_set") {
95+
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
96+
}
97+
98+
// Send the request.
99+
_, _, err := r.query("PUT", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), as, ETag)
100+
if err != nil {
101+
return err
102+
}
103+
104+
return nil
105+
}
106+
107+
// RenameNetworkAddressSet renames an existing network address set entry.
108+
func (r *ProtocolIncus) RenameNetworkAddressSet(name string, as api.NetworkAddressSetPost) error {
109+
if !r.HasExtension("network_address_set") {
110+
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
111+
}
112+
113+
// Send the request.
114+
_, _, err := r.query("POST", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), as, "")
115+
if err != nil {
116+
return err
117+
}
118+
119+
return nil
120+
}
121+
122+
// DeleteNetworkAddressSet deletes an existing network address set.
123+
func (r *ProtocolIncus) DeleteNetworkAddressSet(name string) error {
124+
if !r.HasExtension("network_address_set") {
125+
return fmt.Errorf(`The server is missing the required "network_address_set" API extension`)
126+
}
127+
128+
// Send the request.
129+
_, _, err := r.query("DELETE", fmt.Sprintf("/network-address-sets/%s", url.PathEscape(name)), nil, "")
130+
if err != nil {
131+
return err
132+
}
133+
134+
return nil
135+
}

0 commit comments

Comments
 (0)