| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | // package config contains all the logic around kcrypt config | 
					
						
							|  |  |  | // This config includes everything below `kcrypt:` in the kairos config yaml | 
					
						
							|  |  |  | package config | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2023-03-29 14:14:50 +02:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/jaypipes/ghw/pkg/block" | 
					
						
							| 
									
										
										
										
											2023-06-14 14:26:42 +02:00
										 |  |  | 	"github.com/kairos-io/kairos-sdk/collector" | 
					
						
							| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | 	"github.com/pkg/errors" | 
					
						
							| 
									
										
										
										
											2024-07-15 19:53:00 +02:00
										 |  |  | 	"gopkg.in/yaml.v3" | 
					
						
							| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // There are the directories under which we expect to find kairos configuration. | 
					
						
							|  |  |  | // When we are booted from an iso (during installation), configuration is expected | 
					
						
							|  |  |  | // under `/oem`. When we are booting an installed system (in initramfs phase), | 
					
						
							|  |  |  | // the path is `/sysroot/oem`. | 
					
						
							|  |  |  | var ConfigScanDirs = []string{"/oem", "/sysroot/oem"} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This file is "hardcoded" to `/oem` because we only use this at install time | 
					
						
							|  |  |  | // in which case the config is in `/oem`. | 
					
						
							|  |  |  | var MappingsFile = "/oem/91-kcrypt-mappings.yaml" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Config struct { | 
					
						
							|  |  |  | 	Kcrypt struct { | 
					
						
							|  |  |  | 		UUIDLabelMappings map[string]string `yaml:"uuid_label_mappings,omitempty"` | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func PartitionToString(p *block.Partition) string { | 
					
						
							| 
									
										
										
										
											2023-05-03 15:18:56 +02:00
										 |  |  | 	return fmt.Sprintf("%s:%s:%s", p.FilesystemLabel, p.Name, p.UUID) | 
					
						
							| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Takes a partition info string (as returned by PartitionToString) and return | 
					
						
							|  |  |  | // the partition label and the UUID | 
					
						
							|  |  |  | func partitionDataFromString(partitionStr string) (string, string, error) { | 
					
						
							|  |  |  | 	parts := strings.Split(partitionStr, ":") | 
					
						
							|  |  |  | 	if len(parts) != 3 { | 
					
						
							|  |  |  | 		return "", "", errors.New("partition string not valid") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[2]), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func GetConfiguration(configDirs []string) (Config, error) { | 
					
						
							|  |  |  | 	var result Config | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 14:26:42 +02:00
										 |  |  | 	o := &collector.Options{MergeBootCMDLine: false} | 
					
						
							| 
									
										
										
										
											2023-03-23 17:10:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if err := o.Apply(collector.Directories(configDirs...), collector.NoLogs); err != nil { | 
					
						
							| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 14:26:42 +02:00
										 |  |  | 	c, err := collector.Scan(o, func(d []byte) ([]byte, error) { | 
					
						
							|  |  |  | 		return d, nil | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2023-03-23 17:10:39 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	configStr, err := c.String() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err = yaml.Unmarshal([]byte(configStr), &result); err != nil { | 
					
						
							| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | 		return result, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SetMapping updates the Config with partition information for | 
					
						
							|  |  |  | // one partition. This doesn't persist on the file. WriteMappings needs to | 
					
						
							|  |  |  | // be called after all mapping are in the Config (possibly with multiple calls | 
					
						
							|  |  |  | // to this function). | 
					
						
							|  |  |  | func (c *Config) SetMapping(partitionInfo string) error { | 
					
						
							|  |  |  | 	label, uuid, err := partitionDataFromString(partitionInfo) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Initialize map | 
					
						
							|  |  |  | 	if c.Kcrypt.UUIDLabelMappings == nil { | 
					
						
							|  |  |  | 		c.Kcrypt.UUIDLabelMappings = map[string]string{} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	c.Kcrypt.UUIDLabelMappings[label] = uuid | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // WriteMappings will create or replace the MappingsFile | 
					
						
							|  |  |  | // It's called by kairos agent, at installation time, after the partitions | 
					
						
							|  |  |  | // have been created (and we have the UUIDs available). | 
					
						
							|  |  |  | func (c *Config) WriteMappings(fileName string) error { | 
					
						
							|  |  |  | 	data, err := yaml.Marshal(&c) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return errors.Wrap(err, "marshalling the kcrypt configuration to yaml") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-23 17:10:39 +01:00
										 |  |  | 	data = append([]byte(collector.DefaultHeader+"\n"), data...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 14:14:50 +02:00
										 |  |  | 	err = os.WriteFile(fileName, data, 0744) | 
					
						
							| 
									
										
										
										
											2023-01-13 17:41:39 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return errors.Wrap(err, "writing the kcrypt configuration file") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c Config) LookupUUIDForLabel(l string) string { | 
					
						
							|  |  |  | 	return c.Kcrypt.UUIDLabelMappings[l] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c Config) LookupLabelForUUID(uuid string) string { | 
					
						
							|  |  |  | 	for k, v := range c.Kcrypt.UUIDLabelMappings { | 
					
						
							|  |  |  | 		if v == uuid { | 
					
						
							|  |  |  | 			return k | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return "" | 
					
						
							|  |  |  | } |