1
0
mirror of https://github.com/lxc/incus.git synced 2026-02-05 09:46:19 +01:00

client: Make golangci-lint clean

Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
This commit is contained in:
Stéphane Graber
2025-03-28 19:18:56 -04:00
parent 6e2530cdb0
commit 54e7c21734
10 changed files with 204 additions and 141 deletions

View File

@@ -74,8 +74,8 @@ type ConnectionArgs struct {
// If connecting to an Incus daemon running in PKI mode, the PKI CA (TLSCA) must also be provided.
//
// Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
func ConnectIncus(url string, args *ConnectionArgs) (InstanceServer, error) {
return ConnectIncusWithContext(context.Background(), url, args)
func ConnectIncus(uri string, args *ConnectionArgs) (InstanceServer, error) {
return ConnectIncusWithContext(context.Background(), uri, args)
}
// ConnectIncusWithContext lets you connect to a remote Incus daemon over HTTPs with context.Context.
@@ -85,13 +85,13 @@ func ConnectIncus(url string, args *ConnectionArgs) (InstanceServer, error) {
// If connecting to an Incus daemon running in PKI mode, the PKI CA (TLSCA) must also be provided.
//
// Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
func ConnectIncusWithContext(ctx context.Context, url string, args *ConnectionArgs) (InstanceServer, error) {
func ConnectIncusWithContext(ctx context.Context, uri string, args *ConnectionArgs) (InstanceServer, error) {
// Cleanup URL
url = strings.TrimSuffix(url, "/")
uri = strings.TrimSuffix(uri, "/")
logger.Debug("Connecting to a remote Incus over HTTPS", logger.Ctx{"url": url})
logger.Debug("Connecting to a remote Incus over HTTPS", logger.Ctx{"url": uri})
return httpsIncus(ctx, url, args)
return httpsIncus(ctx, uri, args)
}
// ConnectIncusHTTP lets you connect to a VM agent over a VM socket.
@@ -240,30 +240,30 @@ func ConnectIncusUnixWithContext(ctx context.Context, path string, args *Connect
// ConnectPublicIncus lets you connect to a remote public Incus daemon over HTTPs.
//
// Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
func ConnectPublicIncus(url string, args *ConnectionArgs) (ImageServer, error) {
return ConnectPublicIncusWithContext(context.Background(), url, args)
func ConnectPublicIncus(uri string, args *ConnectionArgs) (ImageServer, error) {
return ConnectPublicIncusWithContext(context.Background(), uri, args)
}
// ConnectPublicIncusWithContext lets you connect to a remote public Incus daemon over HTTPs with context.Context.
//
// Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
func ConnectPublicIncusWithContext(ctx context.Context, url string, args *ConnectionArgs) (ImageServer, error) {
func ConnectPublicIncusWithContext(ctx context.Context, uri string, args *ConnectionArgs) (ImageServer, error) {
logger.Debug("Connecting to a remote public Incus over HTTPS")
// Cleanup URL
url = strings.TrimSuffix(url, "/")
uri = strings.TrimSuffix(uri, "/")
return httpsIncus(ctx, url, args)
return httpsIncus(ctx, uri, args)
}
// ConnectSimpleStreams lets you connect to a remote SimpleStreams image server over HTTPs.
//
// Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert).
func ConnectSimpleStreams(url string, args *ConnectionArgs) (ImageServer, error) {
logger.Debug("Connecting to a remote simplestreams server", logger.Ctx{"URL": url})
func ConnectSimpleStreams(uri string, args *ConnectionArgs) (ImageServer, error) {
logger.Debug("Connecting to a remote simplestreams server", logger.Ctx{"URL": uri})
// Cleanup URL
url = strings.TrimSuffix(url, "/")
uri = strings.TrimSuffix(uri, "/")
// Use empty args if not specified
if args == nil {
@@ -272,7 +272,7 @@ func ConnectSimpleStreams(url string, args *ConnectionArgs) (ImageServer, error)
// Initialize the client struct
server := ProtocolSimpleStreams{
httpHost: url,
httpHost: uri,
httpUserAgent: args.UserAgent,
httpCertificate: args.TLSServerCert,
}
@@ -286,7 +286,7 @@ func ConnectSimpleStreams(url string, args *ConnectionArgs) (ImageServer, error)
server.http = httpClient
// Get simplestreams client
ssClient := simplestreams.NewClient(url, *httpClient, args.UserAgent)
ssClient := simplestreams.NewClient(uri, *httpClient, args.UserAgent)
server.ssClient = ssClient
// Setup the cache
@@ -295,7 +295,7 @@ func ConnectSimpleStreams(url string, args *ConnectionArgs) (ImageServer, error)
return nil, fmt.Errorf("Cache directory %q doesn't exist", args.CachePath)
}
hashedURL := fmt.Sprintf("%x", sha256.Sum256([]byte(url)))
hashedURL := fmt.Sprintf("%x", sha256.Sum256([]byte(uri)))
cachePath := filepath.Join(args.CachePath, hashedURL)
cacheExpiry := args.CacheExpiry

View File

@@ -2,6 +2,7 @@ package incus
import (
"crypto/sha256"
"errors"
"fmt"
"io"
"mime"
@@ -129,7 +130,12 @@ func (r *ProtocolIncus) GetImageSecret(fingerprint string) (string, error) {
opAPI := op.Get()
return opAPI.Metadata["secret"].(string), nil
secret, ok := opAPI.Metadata["secret"].(string)
if !ok {
return "", errors.New("Bad secret type")
}
return secret, nil
}
// GetPrivateImage is similar to GetImage but allows passing a secret download token.
@@ -273,7 +279,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
}
// Hashing
sha256 := sha256.New()
hashSHA256 := sha256.New()
// Deal with split images
if ctype == "multipart/form-data" {
@@ -294,7 +300,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
return nil, fmt.Errorf("Invalid multipart image")
}
size, err := io.Copy(io.MultiWriter(req.MetaFile, sha256), part)
size, err := io.Copy(io.MultiWriter(req.MetaFile, hashSHA256), part)
if err != nil {
return nil, err
}
@@ -312,7 +318,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
return nil, fmt.Errorf("Invalid multipart image")
}
size, err = io.Copy(io.MultiWriter(req.RootfsFile, sha256), part)
size, err = io.Copy(io.MultiWriter(req.RootfsFile, hashSHA256), part)
if err != nil {
return nil, err
}
@@ -321,7 +327,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
resp.RootfsName = part.FileName()
// Check the hash
hash := fmt.Sprintf("%x", sha256.Sum(nil))
hash := fmt.Sprintf("%x", hashSHA256.Sum(nil))
if imageType != "oci" && !strings.HasPrefix(hash, fingerprint) {
return nil, fmt.Errorf("Image fingerprint doesn't match. Got %s expected %s", hash, fingerprint)
}
@@ -340,7 +346,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
return nil, fmt.Errorf("No filename in Content-Disposition header")
}
size, err := io.Copy(io.MultiWriter(req.MetaFile, sha256), body)
size, err := io.Copy(io.MultiWriter(req.MetaFile, hashSHA256), body)
if err != nil {
return nil, err
}
@@ -349,7 +355,7 @@ func incusDownloadImage(fingerprint string, uri string, userAgent string, do fun
resp.MetaName = filename
// Check the hash
hash := fmt.Sprintf("%x", sha256.Sum(nil))
hash := fmt.Sprintf("%x", hashSHA256.Sum(nil))
if imageType != "oci" && !strings.HasPrefix(hash, fingerprint) {
return nil, fmt.Errorf("Image fingerprint doesn't match. Got %s expected %s", hash, fingerprint)
}
@@ -653,18 +659,23 @@ func (r *ProtocolIncus) tryCopyImage(req api.ImagesPost, urls []string) (RemoteO
return
}
var errors []remoteOperationResult
var errs []remoteOperationResult
// Get the operation data
op, err := rop.GetTarget()
if err != nil {
errors = append(errors, remoteOperationResult{Error: err})
rop.err = remoteOperationError("Failed to get operation data", errors)
errs = append(errs, remoteOperationResult{Error: err})
rop.err = remoteOperationError("Failed to get operation data", errs)
return
}
// Extract the fingerprint
fingerprint := op.Metadata["fingerprint"].(string)
fingerprint, ok := op.Metadata["fingerprint"].(string)
if !ok {
errs = append(errs, remoteOperationResult{Error: errors.New("Bad fingerprint")})
rop.err = remoteOperationError("Failed to get operation data", errs)
return
}
// Add the aliases
for _, entry := range req.Aliases {
@@ -674,8 +685,8 @@ func (r *ProtocolIncus) tryCopyImage(req api.ImagesPost, urls []string) (RemoteO
err := r.CreateImageAlias(alias)
if err != nil {
errors = append(errors, remoteOperationResult{Error: err})
rop.err = remoteOperationError("Failed to create image alias", errors)
errs = append(errs, remoteOperationResult{Error: err})
rop.err = remoteOperationError("Failed to create image alias", errs)
return
}
}
@@ -685,13 +696,13 @@ func (r *ProtocolIncus) tryCopyImage(req api.ImagesPost, urls []string) (RemoteO
// Forward targetOp to remote op
go func() {
success := false
var errors []remoteOperationResult
var errs []remoteOperationResult
for _, serverURL := range urls {
req.Source.Server = serverURL
op, err := r.CreateImage(req, nil)
if err != nil {
errors = append(errors, remoteOperationResult{URL: serverURL, Error: err})
errs = append(errs, remoteOperationResult{URL: serverURL, Error: err})
continue
}
@@ -705,7 +716,7 @@ func (r *ProtocolIncus) tryCopyImage(req api.ImagesPost, urls []string) (RemoteO
err = rop.targetOp.Wait()
if err != nil {
errors = append(errors, remoteOperationResult{URL: serverURL, Error: err})
errs = append(errs, remoteOperationResult{URL: serverURL, Error: err})
if localtls.IsConnectionError(err) {
continue
@@ -719,7 +730,7 @@ func (r *ProtocolIncus) tryCopyImage(req api.ImagesPost, urls []string) (RemoteO
}
if !success {
rop.err = remoteOperationError("Failed remote image download", errors)
rop.err = remoteOperationError("Failed remote image download", errs)
}
close(rop.chDone)

View File

@@ -884,7 +884,10 @@ func (r *ProtocolIncus) CopyInstance(source InstanceServer, instance api.Instanc
targetSecrets := map[string]string{}
for k, v := range opAPI.Metadata {
targetSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
targetSecrets[k] = val
}
}
// Prepare the source request
@@ -912,7 +915,10 @@ func (r *ProtocolIncus) CopyInstance(source InstanceServer, instance api.Instanc
sourceSecrets := map[string]string{}
for k, v := range opAPI.Metadata {
sourceSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
sourceSecrets[k] = val
}
}
// Relay mode migration
@@ -932,7 +938,10 @@ func (r *ProtocolIncus) CopyInstance(source InstanceServer, instance api.Instanc
// Extract the websockets
targetSecrets := map[string]string{}
for k, v := range targetOpAPI.Metadata {
targetSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
targetSecrets[k] = val
}
}
// Launch the relay
@@ -1190,9 +1199,14 @@ func (r *ProtocolIncus) ExecInstance(instanceName string, exec api.InstanceExecP
value, ok := opAPI.Metadata["fds"]
if ok {
values := value.(map[string]any)
for k, v := range values {
fds[k] = v.(string)
values, ok := value.(map[string]any)
if ok {
for k, v := range values {
val, ok := v.(string)
if ok {
fds[k] = val
}
}
}
}
@@ -1207,7 +1221,10 @@ func (r *ProtocolIncus) ExecInstance(instanceName string, exec api.InstanceExecP
outputs, ok := opAPI.Metadata["output"].(map[string]any)
if ok {
for k, v := range outputs {
outputFiles[k] = v.(string)
val, ok := v.(string)
if ok {
outputFiles[k] = val
}
}
}
@@ -1811,7 +1828,7 @@ func (r *ProtocolIncus) CopyInstanceSnapshot(source InstanceServer, instanceName
return nil, fmt.Errorf("The server is missing the required \"container_snapshot_stateful_migration\" API extension")
}
req.InstancePut.Stateful = snapshot.Stateful
req.Stateful = snapshot.Stateful
req.Source.Live = false // Snapshots are never running and so we don't need live migration.
}
@@ -1931,7 +1948,10 @@ func (r *ProtocolIncus) CopyInstanceSnapshot(source InstanceServer, instanceName
targetSecrets := map[string]string{}
for k, v := range opAPI.Metadata {
targetSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
targetSecrets[k] = val
}
}
// Prepare the source request
@@ -1959,7 +1979,10 @@ func (r *ProtocolIncus) CopyInstanceSnapshot(source InstanceServer, instanceName
sourceSecrets := map[string]string{}
for k, v := range opAPI.Metadata {
sourceSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
sourceSecrets[k] = val
}
}
// Relay mode migration
@@ -1979,7 +2002,10 @@ func (r *ProtocolIncus) CopyInstanceSnapshot(source InstanceServer, instanceName
// Extract the websockets
targetSecrets := map[string]string{}
for k, v := range targetOpAPI.Metadata {
targetSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
targetSecrets[k] = val
}
}
// Launch the relay
@@ -2234,14 +2260,14 @@ func (r *ProtocolIncus) GetInstanceLogfile(name string, filename string) (io.Rea
}
// Prepare the HTTP request
url := fmt.Sprintf("%s/1.0%s/%s/logs/%s", r.httpBaseURL.String(), path, url.PathEscape(name), url.PathEscape(filename))
uri := fmt.Sprintf("%s/1.0%s/%s/logs/%s", r.httpBaseURL.String(), path, url.PathEscape(name), url.PathEscape(filename))
url, err = r.setQueryAttributes(url)
uri, err = r.setQueryAttributes(uri)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, err
}
@@ -2294,14 +2320,14 @@ func (r *ProtocolIncus) getInstanceExecOutputLogFile(name string, filename strin
}
// Prepare the HTTP request
url := fmt.Sprintf("%s/1.0%s/%s/logs/exec-output/%s", r.httpBaseURL.String(), path, url.PathEscape(name), url.PathEscape(filename))
uri := fmt.Sprintf("%s/1.0%s/%s/logs/exec-output/%s", r.httpBaseURL.String(), path, url.PathEscape(name), url.PathEscape(filename))
url, err = r.setQueryAttributes(url)
uri, err = r.setQueryAttributes(uri)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, err
}
@@ -2357,8 +2383,8 @@ func (r *ProtocolIncus) GetInstanceMetadata(name string) (*api.ImageMetadata, st
metadata := api.ImageMetadata{}
url := fmt.Sprintf("%s/%s/metadata", path, url.PathEscape(name))
etag, err := r.queryStruct("GET", url, nil, "", &metadata)
uri := fmt.Sprintf("%s/%s/metadata", path, url.PathEscape(name))
etag, err := r.queryStruct("GET", uri, nil, "", &metadata)
if err != nil {
return nil, "", err
}
@@ -2377,8 +2403,8 @@ func (r *ProtocolIncus) UpdateInstanceMetadata(name string, metadata api.ImageMe
return fmt.Errorf("The server is missing the required \"container_edit_metadata\" API extension")
}
url := fmt.Sprintf("%s/%s/metadata", path, url.PathEscape(name))
_, _, err = r.query("PUT", url, metadata, ETag)
uri := fmt.Sprintf("%s/%s/metadata", path, url.PathEscape(name))
_, _, err = r.query("PUT", uri, metadata, ETag)
if err != nil {
return err
}
@@ -2399,8 +2425,8 @@ func (r *ProtocolIncus) GetInstanceTemplateFiles(instanceName string) ([]string,
templates := []string{}
url := fmt.Sprintf("%s/%s/metadata/templates", path, url.PathEscape(instanceName))
_, err = r.queryStruct("GET", url, nil, "", &templates)
uri := fmt.Sprintf("%s/%s/metadata/templates", path, url.PathEscape(instanceName))
_, err = r.queryStruct("GET", uri, nil, "", &templates)
if err != nil {
return nil, err
}
@@ -2419,14 +2445,14 @@ func (r *ProtocolIncus) GetInstanceTemplateFile(instanceName string, templateNam
return nil, fmt.Errorf("The server is missing the required \"container_edit_metadata\" API extension")
}
url := fmt.Sprintf("%s/1.0%s/%s/metadata/templates?path=%s", r.httpBaseURL.String(), path, url.PathEscape(instanceName), url.QueryEscape(templateName))
uri := fmt.Sprintf("%s/1.0%s/%s/metadata/templates?path=%s", r.httpBaseURL.String(), path, url.PathEscape(instanceName), url.QueryEscape(templateName))
url, err = r.setQueryAttributes(url)
uri, err = r.setQueryAttributes(uri)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, err
}
@@ -2459,14 +2485,14 @@ func (r *ProtocolIncus) CreateInstanceTemplateFile(instanceName string, template
return fmt.Errorf("The server is missing the required \"container_edit_metadata\" API extension")
}
url := fmt.Sprintf("%s/1.0%s/%s/metadata/templates?path=%s", r.httpBaseURL.String(), path, url.PathEscape(instanceName), url.QueryEscape(templateName))
uri := fmt.Sprintf("%s/1.0%s/%s/metadata/templates?path=%s", r.httpBaseURL.String(), path, url.PathEscape(instanceName), url.QueryEscape(templateName))
url, err = r.setQueryAttributes(url)
uri, err = r.setQueryAttributes(uri)
if err != nil {
return err
}
req, err := http.NewRequest("POST", url, content)
req, err := http.NewRequest("POST", uri, content)
if err != nil {
return err
}
@@ -2553,9 +2579,14 @@ func (r *ProtocolIncus) ConsoleInstance(instanceName string, console api.Instanc
value, ok := opAPI.Metadata["fds"]
if ok {
values := value.(map[string]any)
for k, v := range values {
fds[k] = v.(string)
values, ok := value.(map[string]any)
if ok {
for k, v := range values {
val, ok := v.(string)
if ok {
fds[k] = val
}
}
}
}
@@ -2645,9 +2676,14 @@ func (r *ProtocolIncus) ConsoleInstanceDynamic(instanceName string, console api.
value, ok := opAPI.Metadata["fds"]
if ok {
values := value.(map[string]any)
for k, v := range values {
fds[k] = v.(string)
values, ok := value.(map[string]any)
if ok {
for k, v := range values {
val, ok := v.(string)
if ok {
fds[k] = val
}
}
}
}
@@ -2693,7 +2729,7 @@ func (r *ProtocolIncus) ConsoleInstanceDynamic(instanceName string, console api.
// GetInstanceConsoleLog requests that Incus attaches to the console device of a instance.
//
// Note that it's the caller's responsibility to close the returned ReadCloser.
func (r *ProtocolIncus) GetInstanceConsoleLog(instanceName string, args *InstanceConsoleLogArgs) (io.ReadCloser, error) {
func (r *ProtocolIncus) GetInstanceConsoleLog(instanceName string, _ *InstanceConsoleLogArgs) (io.ReadCloser, error) {
path, _, err := r.instanceTypeToPath(api.InstanceTypeAny)
if err != nil {
return nil, err
@@ -2704,14 +2740,14 @@ func (r *ProtocolIncus) GetInstanceConsoleLog(instanceName string, args *Instanc
}
// Prepare the HTTP request
url := fmt.Sprintf("%s/1.0%s/%s/console", r.httpBaseURL.String(), path, url.PathEscape(instanceName))
uri := fmt.Sprintf("%s/1.0%s/%s/console", r.httpBaseURL.String(), path, url.PathEscape(instanceName))
url, err = r.setQueryAttributes(url)
uri, err = r.setQueryAttributes(uri)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, err
}
@@ -2734,7 +2770,7 @@ func (r *ProtocolIncus) GetInstanceConsoleLog(instanceName string, args *Instanc
}
// DeleteInstanceConsoleLog deletes the requested instance's console log.
func (r *ProtocolIncus) DeleteInstanceConsoleLog(instanceName string, args *InstanceConsoleLogArgs) error {
func (r *ProtocolIncus) DeleteInstanceConsoleLog(instanceName string, _ *InstanceConsoleLogArgs) error {
path, _, err := r.instanceTypeToPath(api.InstanceTypeAny)
if err != nil {
return err

View File

@@ -85,13 +85,13 @@ func (r *ProtocolIncus) GetNetworkACLLogfile(name string) (io.ReadCloser, error)
}
// Prepare the HTTP request
url := fmt.Sprintf("%s/1.0/network-acls/%s/log", r.httpBaseURL.String(), url.PathEscape(name))
url, err := r.setQueryAttributes(url)
uri := fmt.Sprintf("%s/1.0/network-acls/%s/log", r.httpBaseURL.String(), url.PathEscape(name))
uri, err := r.setQueryAttributes(uri)
if err != nil {
return nil, err
}
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, err
}

View File

@@ -47,13 +47,12 @@ func (r *ProtocolIncus) GetOIDCTokens() *oidc.Tokens[*oidc.IDTokenClaims] {
return r.oidcClient.tokens
}
// Custom transport that modifies requests to inject the audience field.
// oidcTransport is a custom HTTP transport that injects the audience field into requests directed at the device authorization endpoint.
type oidcTransport struct {
deviceAuthorizationEndpoint string
audience string
}
// oidcTransport is a custom HTTP transport that injects the audience field into requests directed at the device authorization endpoint.
// RoundTrip is a method of oidcTransport that modifies the request, adds the audience parameter if appropriate, and sends it along.
func (o *oidcTransport) RoundTrip(r *http.Request) (*http.Response, error) {
// Don't modify the request if it's not to the device authorization endpoint, or there are no
@@ -255,12 +254,12 @@ func (o *oidcClient) refresh(issuer string, clientID string) error {
return errRefreshAccessToken
}
o.tokens.Token.AccessToken = oauthTokens.AccessToken
o.tokens.AccessToken = oauthTokens.AccessToken
o.tokens.TokenType = oauthTokens.TokenType
o.tokens.Expiry = oauthTokens.Expiry
if oauthTokens.RefreshToken != "" {
o.tokens.Token.RefreshToken = oauthTokens.RefreshToken
o.tokens.RefreshToken = oauthTokens.RefreshToken
}
return nil
@@ -312,11 +311,11 @@ func (o *oidcClient) authenticate(issuer string, clientID string, audience strin
o.tokens.Expiry = time.Now().Add(time.Duration(token.ExpiresIn))
o.tokens.IDToken = token.IDToken
o.tokens.Token.AccessToken = token.AccessToken
o.tokens.AccessToken = token.AccessToken
o.tokens.TokenType = token.TokenType
if token.RefreshToken != "" {
o.tokens.Token.RefreshToken = token.RefreshToken
o.tokens.RefreshToken = token.RefreshToken
}
return nil

View File

@@ -192,7 +192,7 @@ func (r *ProtocolIncus) GetMetrics() (string, error) {
// ApplyServerPreseed configures a target Incus server with the provided server and cluster configuration.
func (r *ProtocolIncus) ApplyServerPreseed(config api.InitPreseed) error {
// Apply server configuration.
if config.Server.Config != nil && len(config.Server.Config) > 0 {
if len(config.Server.Config) > 0 {
// Get current config.
server, etag, err := r.GetServer()
if err != nil {
@@ -211,7 +211,7 @@ func (r *ProtocolIncus) ApplyServerPreseed(config api.InitPreseed) error {
}
// Apply storage configuration.
if config.Server.StoragePools != nil && len(config.Server.StoragePools) > 0 {
if len(config.Server.StoragePools) > 0 {
// Get the list of storagePools.
storagePoolNames, err := r.GetStoragePoolNames()
if err != nil {
@@ -330,7 +330,7 @@ func (r *ProtocolIncus) ApplyServerPreseed(config api.InitPreseed) error {
}
// Apply project configuration.
if config.Server.Projects != nil && len(config.Server.Projects) > 0 {
if len(config.Server.Projects) > 0 {
// Get the list of projects.
projectNames, err := r.GetProjectNames()
if err != nil {
@@ -469,8 +469,7 @@ func (r *ProtocolIncus) ApplyServerPreseed(config api.InitPreseed) error {
}
// Apply profile configuration.
if config.Server.Profiles != nil && len(config.Server.Profiles) > 0 {
if len(config.Server.Profiles) > 0 {
// Apply profile configuration.
applyProfile := func(profile api.InitProfileProjectPost) error {
// Get the current profile.
@@ -535,7 +534,6 @@ func (r *ProtocolIncus) ApplyServerPreseed(config api.InitPreseed) error {
if err != nil {
return err
}
}
}

View File

@@ -108,12 +108,12 @@ func (r *ProtocolIncus) GetStoragePoolVolumesAllProjects(pool string) ([]api.Sto
volumes := []api.StorageVolume{}
url := api.NewURL().Path("storage-pools", pool, "volumes").
uri := api.NewURL().Path("storage-pools", pool, "volumes").
WithQuery("recursion", "1").
WithQuery("all-projects", "true")
// Fetch the raw value.
_, err = r.queryStruct("GET", url.String(), nil, "", &volumes)
_, err = r.queryStruct("GET", uri.String(), nil, "", &volumes)
if err != nil {
return nil, err
}
@@ -155,13 +155,13 @@ func (r *ProtocolIncus) GetStoragePoolVolumesWithFilterAllProjects(pool string,
volumes := []api.StorageVolume{}
url := api.NewURL().Path("storage-pools", pool, "volumes").
uri := api.NewURL().Path("storage-pools", pool, "volumes").
WithQuery("recursion", "1").
WithQuery("filter", parseFilters(filters)).
WithQuery("all-projects", "true")
// Fetch the raw value.
_, err = r.queryStruct("GET", url.String(), nil, "", &volumes)
_, err = r.queryStruct("GET", uri.String(), nil, "", &volumes)
if err != nil {
return nil, err
}
@@ -636,7 +636,10 @@ func (r *ProtocolIncus) CopyStoragePoolVolume(pool string, source InstanceServer
targetSecrets := map[string]string{}
for k, v := range opAPI.Metadata {
targetSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
targetSecrets[k] = val
}
}
// Prepare the source request
@@ -666,7 +669,10 @@ func (r *ProtocolIncus) CopyStoragePoolVolume(pool string, source InstanceServer
// Prepare source server secrets for remote
sourceSecrets := map[string]string{}
for k, v := range opAPI.Metadata {
sourceSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
sourceSecrets[k] = val
}
}
// Relay mode migration
@@ -689,7 +695,10 @@ func (r *ProtocolIncus) CopyStoragePoolVolume(pool string, source InstanceServer
// Extract the websockets
targetSecrets := map[string]string{}
for k, v := range targetOpAPI.Metadata {
targetSecrets[k] = v.(string)
val, ok := v.(string)
if ok {
targetSecrets[k] = val
}
}
// Launch the relay

View File

@@ -71,7 +71,7 @@ func (r *ProtocolOCI) GetImageFingerprints() ([]string, error) {
}
// GetImagesWithFilter returns a filtered list of available images as Image structs.
func (r *ProtocolOCI) GetImagesWithFilter(filters []string) ([]api.Image, error) {
func (r *ProtocolOCI) GetImagesWithFilter(_ []string) ([]api.Image, error) {
return nil, fmt.Errorf("Can't list images from OCI registry")
}
@@ -320,17 +320,17 @@ func (r *ProtocolOCI) GetImageFile(fingerprint string, req ImageFileRequest) (*I
}
// GetImageSecret isn't relevant for the simplestreams protocol.
func (r *ProtocolOCI) GetImageSecret(fingerprint string) (string, error) {
func (r *ProtocolOCI) GetImageSecret(_ string) (string, error) {
return "", fmt.Errorf("Private images aren't supported with OCI registry")
}
// GetPrivateImage isn't relevant for the simplestreams protocol.
func (r *ProtocolOCI) GetPrivateImage(fingerprint string, secret string) (*api.Image, string, error) {
func (r *ProtocolOCI) GetPrivateImage(_ string, _ string) (*api.Image, string, error) {
return nil, "", fmt.Errorf("Private images aren't supported with OCI registry")
}
// GetPrivateImageFile isn't relevant for the simplestreams protocol.
func (r *ProtocolOCI) GetPrivateImageFile(fingerprint string, secret string, req ImageFileRequest) (*ImageFileResponse, error) {
func (r *ProtocolOCI) GetPrivateImageFile(_ string, _ string, _ ImageFileRequest) (*ImageFileResponse, error) {
return nil, fmt.Errorf("Private images aren't supported with OCI registry")
}
@@ -439,6 +439,6 @@ func (r *ProtocolOCI) GetImageAliasArchitectures(imageType string, name string)
}
// ExportImage exports (copies) an image to a remote server.
func (r *ProtocolOCI) ExportImage(fingerprint string, image api.ImageExportPost) (Operation, error) {
func (r *ProtocolOCI) ExportImage(_ string, _ api.ImageExportPost) (Operation, error) {
return nil, fmt.Errorf("Exporting images is not supported with OCI registry")
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/lxc/incus/v6/shared/api"
"github.com/lxc/incus/v6/shared/logger"
"github.com/lxc/incus/v6/shared/simplestreams"
"github.com/lxc/incus/v6/shared/subprocess"
"github.com/lxc/incus/v6/shared/util"
)
@@ -54,7 +55,7 @@ func (r *ProtocolSimpleStreams) GetImageFingerprints() ([]string, error) {
}
// GetImagesWithFilter returns a filtered list of available images as Image structs.
func (r *ProtocolSimpleStreams) GetImagesWithFilter(filters []string) ([]api.Image, error) {
func (r *ProtocolSimpleStreams) GetImagesWithFilter(_ []string) ([]api.Image, error) {
return nil, fmt.Errorf("GetImagesWithFilter is not supported by the simplestreams protocol")
}
@@ -160,6 +161,48 @@ func (r *ProtocolSimpleStreams) GetImageFile(fingerprint string, req ImageFileRe
downloaded := false
_, err := exec.LookPath("xdelta3")
if err == nil && req.DeltaSourceRetriever != nil {
applyDelta := func(file simplestreams.DownloadableFile, srcPath string, target io.Writer) (int64, error) {
// Create temporary file for the delta
deltaFile, err := os.CreateTemp("", "incus_image_")
if err != nil {
return -1, err
}
defer func() { _ = deltaFile.Close() }()
defer func() { _ = os.Remove(deltaFile.Name()) }()
// Download the delta
_, err = download(file.Path, "rootfs delta", file.Sha256, deltaFile)
if err != nil {
return -1, err
}
// Create temporary file for the delta
patchedFile, err := os.CreateTemp("", "incus_image_")
if err != nil {
return -1, err
}
defer func() { _ = patchedFile.Close() }()
defer func() { _ = os.Remove(patchedFile.Name()) }()
// Apply it
_, err = subprocess.RunCommand("xdelta3", "-f", "-d", "-s", srcPath, deltaFile.Name(), patchedFile.Name())
if err != nil {
return -1, err
}
// Copy to the target
size, err := io.Copy(req.RootfsFile, patchedFile)
if err != nil {
return -1, err
}
return size, nil
}
for filename, file := range files {
_, srcFingerprint, prefixFound := strings.Cut(filename, "root.delta-")
if !prefixFound {
@@ -172,40 +215,7 @@ func (r *ProtocolSimpleStreams) GetImageFile(fingerprint string, req ImageFileRe
continue
}
// Create temporary file for the delta
deltaFile, err := os.CreateTemp("", "incus_image_")
if err != nil {
return nil, err
}
defer func() { _ = deltaFile.Close() }()
defer func() { _ = os.Remove(deltaFile.Name()) }()
// Download the delta
_, err = download(file.Path, "rootfs delta", file.Sha256, deltaFile)
if err != nil {
return nil, err
}
// Create temporary file for the delta
patchedFile, err := os.CreateTemp("", "incus_image_")
if err != nil {
return nil, err
}
defer func() { _ = patchedFile.Close() }()
defer func() { _ = os.Remove(patchedFile.Name()) }()
// Apply it
_, err = subprocess.RunCommand("xdelta3", "-f", "-d", "-s", srcPath, deltaFile.Name(), patchedFile.Name())
if err != nil {
return nil, err
}
// Copy to the target
size, err := io.Copy(req.RootfsFile, patchedFile)
size, err := applyDelta(file, srcPath, req.RootfsFile)
if err != nil {
return nil, err
}
@@ -234,17 +244,17 @@ func (r *ProtocolSimpleStreams) GetImageFile(fingerprint string, req ImageFileRe
}
// GetImageSecret isn't relevant for the simplestreams protocol.
func (r *ProtocolSimpleStreams) GetImageSecret(fingerprint string) (string, error) {
func (r *ProtocolSimpleStreams) GetImageSecret(_ string) (string, error) {
return "", fmt.Errorf("Private images aren't supported by the simplestreams protocol")
}
// GetPrivateImage isn't relevant for the simplestreams protocol.
func (r *ProtocolSimpleStreams) GetPrivateImage(fingerprint string, secret string) (*api.Image, string, error) {
func (r *ProtocolSimpleStreams) GetPrivateImage(_ string, _ string) (*api.Image, string, error) {
return nil, "", fmt.Errorf("Private images aren't supported by the simplestreams protocol")
}
// GetPrivateImageFile isn't relevant for the simplestreams protocol.
func (r *ProtocolSimpleStreams) GetPrivateImageFile(fingerprint string, secret string, req ImageFileRequest) (*ImageFileResponse, error) {
func (r *ProtocolSimpleStreams) GetPrivateImageFile(_ string, _ string, _ ImageFileRequest) (*ImageFileResponse, error) {
return nil, fmt.Errorf("Private images aren't supported by the simplestreams protocol")
}
@@ -315,6 +325,6 @@ func (r *ProtocolSimpleStreams) GetImageAliasArchitectures(imageType string, nam
}
// ExportImage exports (copies) an image to a remote server.
func (r *ProtocolSimpleStreams) ExportImage(fingerprint string, image api.ImageExportPost) (Operation, error) {
func (r *ProtocolSimpleStreams) ExportImage(_ string, _ api.ImageExportPost) (Operation, error) {
return nil, fmt.Errorf("Exporting images is not supported by the simplestreams protocol")
}

View File

@@ -116,7 +116,7 @@ func tlsHTTPClient(client *http.Client, tlsClientCert string, tlsClientKey strin
// Any errors encountered during the setup process are also handled by the function.
func unixHTTPClient(args *ConnectionArgs, path string) (*http.Client, error) {
// Setup a Unix socket dialer
unixDial := func(_ context.Context, network, addr string) (net.Conn, error) {
unixDial := func(_ context.Context, _ string, _ string) (net.Conn, error) {
raddr, err := net.ResolveUnixAddr("unix", path)
if err != nil {
return nil, err