diff --git a/runner/providers/lxd/images.go b/runner/providers/lxd/images.go index ae90434d..8e407c56 100644 --- a/runner/providers/lxd/images.go +++ b/runner/providers/lxd/images.go @@ -16,7 +16,6 @@ package lxd import ( "fmt" - "log" "strings" "github.com/cloudbase/garm/config" @@ -65,83 +64,26 @@ func (i *image) getLocalImageByAlias(imageName string, imageType config.LXDImage return image, nil } -func (i *image) clientFromRemoteArgs(remote config.LXDImageRemote) (lxd.ImageServer, error) { - connectArgs := &lxd.ConnectionArgs{ - InsecureSkipVerify: remote.InsecureSkipVerify, +func (i *image) getInstanceSource(imageName string, imageType config.LXDImageType, arch string, cli lxd.InstanceServer) (api.InstanceSource, error) { + instanceSource := api.InstanceSource{ + Type: "image", } - d, err := lxd.ConnectSimpleStreams(remote.Address, connectArgs) - if err != nil { - return nil, errors.Wrapf(err, "connecting to image server %s", remote.Address) - } - return d, nil -} - -func (i *image) copyImageFromRemote(remote config.LXDImageRemote, imageName string, imageType config.LXDImageType, arch string, cli lxd.InstanceServer) (*api.Image, error) { - imgCli, err := i.clientFromRemoteArgs(remote) - if err != nil { - return nil, errors.Wrap(err, "fetching image server client") - } - defer imgCli.Disconnect() - - aliases, err := imgCli.GetImageAliasArchitectures(imageType.String(), imageName) - if err != nil { - return nil, errors.Wrapf(err, "resolving alias: %s", imageName) - } - - alias, ok := aliases[arch] - if !ok { - return nil, fmt.Errorf("no image found for arch %s and image type %s with name %s", arch, imageType, imageName) - } - - image, _, err := imgCli.GetImage(alias.Target) - if err != nil { - return nil, errors.Wrap(err, "fetching image details") - } - - imgCopyArgs := &lxd.ImageCopyArgs{ - AutoUpdate: true, - } - - op, err := cli.CopyImage(imgCli, *image, imgCopyArgs) - if err != nil { - return nil, errors.Wrapf(err, "copying image %s from %s", imageName, remote.Address) - } - - // And wait for it to finish - err = op.Wait() - if err != nil { - return nil, errors.Wrap(err, "waiting for image copy operation") - } - - return image, nil -} - -// EnsureImage will look for an image locally, then attempt to download it from a remote -// server, if the name contains a remote. Allowed formats are: -// remote_name:image_name -// image_name -func (i *image) EnsureImage(imageName string, imageType config.LXDImageType, arch string, cli lxd.InstanceServer) (*api.Image, error) { if !strings.Contains(imageName, ":") { // A remote was not specified, try to find an image using the imageName as // an alias. - return i.getLocalImageByAlias(imageName, imageType, arch, cli) - } - - remote, parsedName, err := i.parseImageName(imageName) - if err != nil { - return nil, errors.Wrap(err, "parsing image name") - } - - if img, err := i.copyImageFromRemote(remote, parsedName, imageType, arch, cli); err == nil { - return img, nil + imageDetails, err := i.getLocalImageByAlias(imageName, imageType, arch, cli) + if err != nil { + return api.InstanceSource{}, errors.Wrap(err, "fetching image") + } + instanceSource.Fingerprint = imageDetails.Fingerprint } else { - log.Printf("failed to fetch image of type %v with name %s and arch %s: %s", imageType, parsedName, arch, err) + remote, parsedName, err := i.parseImageName(imageName) + if err != nil { + return api.InstanceSource{}, errors.Wrap(err, "parsing image name") + } + instanceSource.Alias = parsedName + instanceSource.Server = remote.Address + instanceSource.Protocol = string(remote.Protocol) } - - log.Printf("attempting to find %s for arch %s locally", parsedName, arch) - img, err := i.getLocalImageByAlias(parsedName, imageType, arch, cli) - if err != nil { - return nil, errors.Wrap(err, "fetching image") - } - return img, nil + return instanceSource, nil } diff --git a/runner/providers/lxd/lxd.go b/runner/providers/lxd/lxd.go index dea9c409..e76c30e6 100644 --- a/runner/providers/lxd/lxd.go +++ b/runner/providers/lxd/lxd.go @@ -17,7 +17,6 @@ package lxd import ( "context" "fmt" - "log" "sync" "github.com/cloudbase/garm/config" @@ -170,21 +169,7 @@ func (l *LXD) getProfiles(flavor string) ([]string, error) { return ret, nil } -func (l *LXD) getTools(image *api.Image, tools []*github.RunnerApplicationDownload, assumedOSType params.OSType) (github.RunnerApplicationDownload, error) { - if image == nil { - return github.RunnerApplicationDownload{}, fmt.Errorf("nil image received") - } - osName, ok := image.ImagePut.Properties["os"] - if !ok { - return github.RunnerApplicationDownload{}, fmt.Errorf("missing OS info in image properties") - } - - osType, err := util.OSToOSType(osName) - if err != nil { - log.Printf("failed to determine OS type from image, assuming %s", assumedOSType) - osType = assumedOSType - } - +func (l *LXD) getTools(tools []*github.RunnerApplicationDownload, osType params.OSType, architecture string) (github.RunnerApplicationDownload, error) { // Validate image OS. Linux only for now. switch osType { case params.Linux: @@ -203,16 +188,16 @@ func (l *LXD) getTools(image *api.Image, tools []*github.RunnerApplicationDownlo // fmt.Println(*tool.Architecture, *tool.OS) // fmt.Printf("image arch: %s --> osType: %s\n", image.Architecture, string(osType)) - if *tool.Architecture == image.Architecture && *tool.OS == string(osType) { + if *tool.Architecture == architecture && *tool.OS == string(osType) { return *tool, nil } - arch, ok := lxdToGithubArchMap[image.Architecture] + arch, ok := lxdToGithubArchMap[architecture] if ok && arch == *tool.Architecture && *tool.OS == string(osType) { return *tool, nil } } - return github.RunnerApplicationDownload{}, fmt.Errorf("failed to find tools for OS %s and arch %s", osType, image.Architecture) + return github.RunnerApplicationDownload{}, fmt.Errorf("failed to find tools for OS %s and arch %s", osType, architecture) } // sadly, the security.secureboot flag is a string encoded boolean. @@ -238,13 +223,12 @@ func (l *LXD) getCreateInstanceArgs(bootstrapParams params.BootstrapInstance) (a } instanceType := l.cfg.LXD.GetInstanceType() - - image, err := l.imageManager.EnsureImage(bootstrapParams.Image, instanceType, arch, l.cli) + instanceSource, err := l.imageManager.getInstanceSource(bootstrapParams.Image, instanceType, arch, l.cli) if err != nil { - return api.InstancesPost{}, errors.Wrap(err, "getting image details") + return api.InstancesPost{}, errors.Wrap(err, "getting instance source") } - tools, err := l.getTools(image, bootstrapParams.Tools, bootstrapParams.OSType) + tools, err := l.getTools(bootstrapParams.Tools, bootstrapParams.OSType, arch) if err != nil { return api.InstancesPost{}, errors.Wrap(err, "getting tools") } @@ -268,17 +252,14 @@ func (l *LXD) getCreateInstanceArgs(bootstrapParams params.BootstrapInstance) (a args := api.InstancesPost{ InstancePut: api.InstancePut{ - Architecture: image.Architecture, + Architecture: arch, Profiles: profiles, Description: "Github runner provisioned by garm", Config: configMap, }, - Source: api.InstanceSource{ - Type: "image", - Fingerprint: image.Fingerprint, - }, - Name: bootstrapParams.Name, - Type: api.InstanceType(instanceType), + Source: instanceSource, + Name: bootstrapParams.Name, + Type: api.InstanceType(instanceType), } return args, nil }