diff --git a/docs/index.md b/docs/index.md index d3593f6e..97c077e9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -77,7 +77,7 @@ The following arguments are supported: The `remote` block supports: -* `address` - *Optional* - The address of the LXD remote. +* `address` - *Optional* - The address of the remote. * `default` - *Optional* - Whether this should be the default remote. This remote will then be used when one is not specified in a resource. @@ -88,14 +88,16 @@ The `remote` block supports: for more information. The default can also be set with the `LXD_REMOTE` Environment variable. -* `name` - *Optional* - The name of the LXD remote. +* `name` - *Optional* - The name of the remote. * `password` - *Optional* - The password to authenticate to the LXD remote. -* `port` - *Optional* - The port of the LXD remote. +* `port` - *Optional* - The port of the remote. -* `scheme` - *Optional* Whether to connect to the LXD remote via `https` or - `unix` (UNIX socket). Defaults to `unix`. +* `protocol` - *Optional* - The protocol of remote server (`lxd` or `simplestreams`). + +* `scheme` - *Optional* Whether to connect to the remote via `https` or + `unix` (UNIX socket). Defaults to `unix` for LXD remote and `https` for simplestreams remote. ## Undefined Remote diff --git a/internal/instance/resource_instance_test.go b/internal/instance/resource_instance_test.go index 80ba7063..0b9452f6 100644 --- a/internal/instance/resource_instance_test.go +++ b/internal/instance/resource_instance_test.go @@ -1168,6 +1168,24 @@ func TestAccInstance_removeProject(t *testing.T) { }) } +func TestAccInstance_customImageServer(t *testing.T) { + instanceName := acctest.GenerateName(2, "-") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccInstance_customImageServer(instanceName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("lxd_instance.instance1", "name", instanceName), + resource.TestCheckResourceAttr("lxd_instance.instance1", "status", "Running"), + ), + }, + }, + }) +} + func TestAccInstance_timeout(t *testing.T) { instanceName := acctest.GenerateName(2, "-") @@ -2069,6 +2087,23 @@ resource "lxd_instance" "instance1" { `, projectName, instanceName, acctest.TestImage) } +func testAccInstance_customImageServer(instanceName string) string { + return fmt.Sprintf(` +provider "lxd" { + remote { + name = "images-temporary" + address = "images.lxd.canonical.com" + protocol = "simplestreams" + } +} + +resource "lxd_instance" "instance1" { + name = "%s" + image = "images-temporary:alpine/edge" +} + `, instanceName) +} + func testAccInstance_timeout(instanceName string) string { return fmt.Sprintf(` resource "lxd_instance" "instance1" { diff --git a/internal/provider-config/config.go b/internal/provider-config/config.go index a1634022..ae3f6d2c 100644 --- a/internal/provider-config/config.go +++ b/internal/provider-config/config.go @@ -29,6 +29,7 @@ type LxdProviderRemoteConfig struct { Address string Port string Password string + Protocol string Scheme string Bootstrapped bool } @@ -202,15 +203,14 @@ func (p *LxdProviderConfig) createLxdServerClient(remote LxdProviderRemoteConfig return nil } - daemonAddr, err := determineLxdDaemonAddr(remote) - if err != nil { - return fmt.Errorf("Unable to determine daemon address for remote %q: %v", remote.Name, err) + lxdRemote := lxd_config.Remote{ + Addr: determineLxdDaemonAddr(remote), + Protocol: remote.Protocol, } - lxdRemote := lxd_config.Remote{Addr: daemonAddr} p.setLxdConfigRemote(remote.Name, lxdRemote) - if remote.Scheme == "https" { + if remote.Scheme == "https" && remote.Protocol == "lxd" { // If the LXD remote's certificate does not exist on the client... p.mux.RLock() certPath := p.lxdConfig.ServerCertPath(remote.Name) @@ -366,7 +366,7 @@ func connectToLxdServer(instServer lxd.InstanceServer) error { } // determineLxdDaemonAddr determines address of the LXD server daemon. -func determineLxdDaemonAddr(remote LxdProviderRemoteConfig) (string, error) { +func determineLxdDaemonAddr(remote LxdProviderRemoteConfig) string { var daemonAddr string if remote.Address != "" { @@ -378,7 +378,7 @@ func determineLxdDaemonAddr(remote LxdProviderRemoteConfig) (string, error) { } } - return daemonAddr, nil + return daemonAddr } // determineLxdDir determines which standard LXD directory contains a writable UNIX socket. diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 48cae4d8..53bbc9ed 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -29,6 +29,7 @@ type LxdProviderRemoteModel struct { Name types.String `tfsdk:"name"` Address types.String `tfsdk:"address"` Port types.String `tfsdk:"port"` + Protocol types.String `tfsdk:"protocol"` Password types.String `tfsdk:"password"` Scheme types.String `tfsdk:"scheme"` Default types.Bool `tfsdk:"default"` @@ -120,6 +121,14 @@ func (p *LxdProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp * Description: "The password for the remote.", }, + "protocol": schema.StringAttribute{ + Optional: true, + Description: "Remote protocol", + Validators: []validator.String{ + stringvalidator.OneOf("lxd", "simplestreams"), + }, + }, + "default": schema.BoolAttribute{ Optional: true, Description: "Set this remote as default.", @@ -221,6 +230,7 @@ func (p *LxdProvider) Configure(ctx context.Context, req provider.ConfigureReque Port: os.Getenv("LXD_PORT"), Password: os.Getenv("LXD_PASSWORD"), Scheme: os.Getenv("LXD_SCHEME"), + Protocol: "lxd", } // This will be the default remote unless overridden by an @@ -239,25 +249,42 @@ func (p *LxdProvider) Configure(ctx context.Context, req provider.ConfigureReque // in Terraform configurations where the LXD remote might not // exist yet. for _, remote := range data.Remotes { + protocol := remote.Protocol.ValueString() + if protocol == "" { + protocol = "lxd" + } + port := remote.Port.ValueString() if port == "" { port = "8443" + if protocol == "simplestreams" { + port = "443" + } } scheme := remote.Scheme.ValueString() if scheme == "" { scheme = "unix" + if protocol == "simplestreams" { + scheme = "https" + } } lxdRemote := provider_config.LxdProviderRemoteConfig{ Name: remote.Name.ValueString(), Password: remote.Password.ValueString(), Address: remote.Address.ValueString(), + Protocol: protocol, Port: port, Scheme: scheme, } isDefault := remote.Default.ValueBool() + if protocol == "simplestreams" { + // Simplestreams cannot be default. + isDefault = false + } + lxdProvider.SetRemote(lxdRemote, isDefault) }