File: instances.go

package info (click to toggle)
incus 6.0.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,392 kB
  • sloc: sh: 16,313; ansic: 3,121; python: 457; makefile: 337; ruby: 51; sql: 50; lisp: 6
file content (170 lines) | stat: -rw-r--r-- 5,771 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//go:build linux && cgo && !agent

package cluster

import (
	"context"
	"database/sql"
	"time"

	"github.com/lxc/incus/v6/internal/server/device/config"
	"github.com/lxc/incus/v6/internal/server/instance/instancetype"
	"github.com/lxc/incus/v6/shared/api"
	"github.com/lxc/incus/v6/shared/osarch"
)

// Code generation directives.
//
//generate-database:mapper target instances.mapper.go
//generate-database:mapper reset -i -b "//go:build linux && cgo && !agent"
//
//generate-database:mapper stmt -e instance objects
//generate-database:mapper stmt -e instance objects-by-ID
//generate-database:mapper stmt -e instance objects-by-Project
//generate-database:mapper stmt -e instance objects-by-Project-and-Type
//generate-database:mapper stmt -e instance objects-by-Project-and-Type-and-Node
//generate-database:mapper stmt -e instance objects-by-Project-and-Type-and-Node-and-Name
//generate-database:mapper stmt -e instance objects-by-Project-and-Type-and-Name
//generate-database:mapper stmt -e instance objects-by-Project-and-Name
//generate-database:mapper stmt -e instance objects-by-Project-and-Name-and-Node
//generate-database:mapper stmt -e instance objects-by-Project-and-Node
//generate-database:mapper stmt -e instance objects-by-Type
//generate-database:mapper stmt -e instance objects-by-Type-and-Name
//generate-database:mapper stmt -e instance objects-by-Type-and-Name-and-Node
//generate-database:mapper stmt -e instance objects-by-Type-and-Node
//generate-database:mapper stmt -e instance objects-by-Node
//generate-database:mapper stmt -e instance objects-by-Node-and-Name
//generate-database:mapper stmt -e instance objects-by-Name
//generate-database:mapper stmt -e instance id
//generate-database:mapper stmt -e instance create
//generate-database:mapper stmt -e instance rename
//generate-database:mapper stmt -e instance delete-by-Project-and-Name
//generate-database:mapper stmt -e instance update
//
//generate-database:mapper method -i -e instance GetMany references=Config,Device
//generate-database:mapper method -i -e instance GetOne
//generate-database:mapper method -i -e instance ID
//generate-database:mapper method -i -e instance Exists
//generate-database:mapper method -i -e instance Create references=Config,Device
//generate-database:mapper method -i -e instance Rename
//generate-database:mapper method -i -e instance DeleteOne-by-Project-and-Name
//generate-database:mapper method -i -e instance Update references=Config,Device

// Instance is a value object holding db-related details about an instance.
type Instance struct {
	ID           int
	Project      string `db:"primary=yes&join=projects.name"`
	Name         string `db:"primary=yes"`
	Node         string `db:"join=nodes.name"`
	Type         instancetype.Type
	Snapshot     bool `db:"ignore"`
	Architecture int
	Ephemeral    bool
	CreationDate time.Time
	Stateful     bool
	LastUseDate  sql.NullTime
	Description  string `db:"coalesce=''"`
	ExpiryDate   sql.NullTime
}

// InstanceFilter specifies potential query parameter fields.
type InstanceFilter struct {
	ID      *int
	Project *string
	Name    *string
	Node    *string
	Type    *instancetype.Type
}

// ToAPI converts the database Instance to API type.
func (i *Instance) ToAPI(ctx context.Context, tx *sql.Tx, instanceDevices map[int][]Device, profileConfigs map[int]map[string]string, profileDevices map[int][]Device) (*api.Instance, error) {
	profiles, err := GetInstanceProfiles(ctx, tx, i.ID)
	if err != nil {
		return nil, err
	}

	if profileConfigs == nil {
		profileConfigs, err = GetAllProfileConfigs(ctx, tx)
		if err != nil {
			return nil, err
		}
	}

	if profileDevices == nil {
		profileDevices, err = GetAllProfileDevices(ctx, tx)
		if err != nil {
			return nil, err
		}
	}

	apiProfiles := make([]api.Profile, 0, len(profiles))
	profileNames := make([]string, 0, len(profiles))
	for _, p := range profiles {
		apiProfile, err := p.ToAPI(ctx, tx, profileConfigs, profileDevices)
		if err != nil {
			return nil, err
		}

		apiProfiles = append(apiProfiles, *apiProfile)
		profileNames = append(profileNames, p.Name)
	}

	var devices map[string]Device
	if instanceDevices != nil {
		devices = map[string]Device{}

		for _, dev := range instanceDevices[i.ID] {
			devices[dev.Name] = dev
		}
	} else {
		devices, err = GetInstanceDevices(ctx, tx, i.ID)
		if err != nil {
			return nil, err
		}
	}

	apiDevices := DevicesToAPI(devices)
	expandedDevices := ExpandInstanceDevices(config.NewDevices(apiDevices), apiProfiles)

	config, err := GetInstanceConfig(ctx, tx, i.ID)
	if err != nil {
		return nil, err
	}

	expandedConfig := ExpandInstanceConfig(config, apiProfiles)

	archName, err := osarch.ArchitectureName(i.Architecture)
	if err != nil {
		return nil, err
	}

	return &api.Instance{
		InstancePut: api.InstancePut{
			Architecture: archName,
			Config:       config,
			Devices:      apiDevices,
			Ephemeral:    i.Ephemeral,
			Profiles:     profileNames,
			Stateful:     i.Stateful,
			Description:  i.Description,
		},
		CreatedAt:       i.CreationDate,
		ExpandedConfig:  expandedConfig,
		ExpandedDevices: expandedDevices.CloneNative(),
		Name:            i.Name,
		LastUsedAt:      i.LastUseDate.Time,
		Location:        i.Node,
		Type:            i.Type.String(),
		Project:         i.Project,
	}, nil
}

// GetAllInstanceConfigs returns a map of all instance configurations, keyed by database ID.
func GetAllInstanceConfigs(ctx context.Context, tx *sql.Tx) (map[int]map[string]string, error) {
	return GetConfig(ctx, tx, "instances", "instance")
}

// GetAllInstanceDevices returns a map of all instance devices, keyed by database ID.
func GetAllInstanceDevices(ctx context.Context, tx *sql.Tx) (map[int][]Device, error) {
	return GetDevices(ctx, tx, "instances", "instance")
}