@@ -12,10 +12,127 @@ import (
1212 apierrors "k8s.io/apimachinery/pkg/api/errors"
1313 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1414 "k8s.io/apimachinery/pkg/types"
15+ )
16+
17+ var (
18+ // ErrMissingName is the error returned when the WorfklowTemplate Name is not specified.
19+ ErrMissingName = fmt .Errorf ("name can't be empty" )
20+
21+ // ErrMissingImageURL is the error returned when the WorfklowTemplate ImageURL is not specified.
22+ ErrMissingImageURL = fmt .Errorf ("imageURL can't be empty" )
23+ )
1524
16- "github.com/tinkerbell/cluster-api-provider-tinkerbell/internal/templates"
25+ const (
26+ workflowTemplate = `
27+ version: "0.1"
28+ name: {{.Name}}
29+ global_timeout: 6000
30+ tasks:
31+ - name: "{{.Name}}"
32+ worker: "{{.DeviceTemplateName}}"
33+ volumes:
34+ - /dev:/dev
35+ - /dev/console:/dev/console
36+ - /lib/firmware:/lib/firmware:ro
37+ actions:
38+ - name: "stream-image"
39+ image: quay.io/tinkerbell-actions/oci2disk:v1.0.0
40+ timeout: 600
41+ environment:
42+ IMG_URL: {{.ImageURL}}
43+ DEST_DISK: {{.DestDisk}}
44+ COMPRESSED: true
45+ - name: "add-tink-cloud-init-config"
46+ image: quay.io/tinkerbell-actions/writefile:v1.0.0
47+ timeout: 90
48+ environment:
49+ DEST_DISK: {{.DestPartition}}
50+ FS_TYPE: ext4
51+ DEST_PATH: /etc/cloud/cloud.cfg.d/10_tinkerbell.cfg
52+ UID: 0
53+ GID: 0
54+ MODE: 0600
55+ DIRMODE: 0700
56+ CONTENTS: |
57+ datasource:
58+ Ec2:
59+ metadata_urls: ["{{.MetadataURL}}"]
60+ strict_id: false
61+ system_info:
62+ default_user:
63+ name: tink
64+ groups: [wheel, adm]
65+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
66+ shell: /bin/bash
67+ manage_etc_hosts: localhost
68+ warnings:
69+ dsid_missing_source: off
70+ - name: "add-tink-cloud-init-ds-config"
71+ image: quay.io/tinkerbell-actions/writefile:v1.0.0
72+ timeout: 90
73+ environment:
74+ DEST_DISK: {{.DestPartition}}
75+ FS_TYPE: ext4
76+ DEST_PATH: /etc/cloud/ds-identify.cfg
77+ UID: 0
78+ GID: 0
79+ MODE: 0600
80+ DIRMODE: 0700
81+ CONTENTS: |
82+ datasource: Ec2
83+ - name: "kexec-image"
84+ image: ghcr.io/jacobweinstock/waitdaemon:0.1.2
85+ timeout: 90
86+ pid: host
87+ environment:
88+ BLOCK_DEVICE: {{.DestPartition}}
89+ FS_TYPE: ext4
90+ IMAGE: quay.io/tinkerbell-actions/kexec:v1.0.0
91+ WAIT_SECONDS: 10
92+ volumes:
93+ - /var/run/docker.sock:/var/run/docker.sock
94+ `
1795)
1896
97+ // WorkflowTemplate is a helper struct for rendering CAPT Template data.
98+ type WorkflowTemplate struct {
99+ Name string
100+ MetadataURL string
101+ ImageURL string
102+ DestDisk string
103+ DestPartition string
104+ DeviceTemplateName string
105+ }
106+
107+ // Render renders workflow template for a given machine including user-data.
108+ func (wt * WorkflowTemplate ) Render () (string , error ) {
109+ if wt .Name == "" {
110+ return "" , ErrMissingName
111+ }
112+
113+ if wt .ImageURL == "" {
114+ return "" , ErrMissingImageURL
115+ }
116+
117+ if wt .DeviceTemplateName == "" {
118+ wt .DeviceTemplateName = "{{.device_1}}"
119+ }
120+
121+ tpl , err := template .New ("template" ).Parse (workflowTemplate )
122+ if err != nil {
123+ return "" , fmt .Errorf ("unable to parse template: %w" , err )
124+ }
125+
126+ buf := & bytes.Buffer {}
127+
128+ err = tpl .Execute (buf , wt )
129+ if err != nil {
130+ return "" , fmt .Errorf ("unable to execute template: %w" , err )
131+ }
132+
133+ return buf .String (), nil
134+ }
135+
19136func (scope * machineReconcileScope ) templateExists () (bool , error ) {
20137 namespacedName := types.NamespacedName {
21138 Name : scope .tinkerbellMachine .Name ,
@@ -56,7 +173,7 @@ func (scope *machineReconcileScope) createTemplate(hw *tinkv1.Hardware) error {
56173
57174 metadataURL := fmt .Sprintf ("http://%s:50061" , metadataIP )
58175
59- workflowTemplate := templates. WorkflowTemplate {
176+ workflowTemplate := WorkflowTemplate {
60177 Name : scope .tinkerbellMachine .Name ,
61178 MetadataURL : metadataURL ,
62179 ImageURL : imageURL ,
0 commit comments