installer-env: render dns records to publish
diff --git a/core/installer/welcome/env-created.html b/core/installer/welcome/env-created.html
index 26f551a..5e54fb3 100644
--- a/core/installer/welcome/env-created.html
+++ b/core/installer/welcome/env-created.html
@@ -20,7 +20,7 @@
 		<meta charset="utf-8" />
 		<meta name="viewport" content="width=device-width, initial-scale=1" />
 		{{ if not (or (eq .Root.Status 2) (eq .Root.Status 3))}}
-		<meta http-equiv="refresh" content="2">
+		<meta http-equiv="refresh" content="10">
 		{{ end }}
 	</head>
 	<body>
@@ -35,6 +35,19 @@
 			</ul>
 		</nav>
 		<main class="container">
+			{{ if .DNSRecords }}
+			<form action="" method="POST">
+				You will have to publish following DNS records via your domain registrar.
+				<textarea disabled>{{ .DNSRecords }}</textarea>
+				<label for="domain-registrar">Domain Registrar</label>
+				<select id="domain-registrar" required>
+					<option value="" selected>Select registrar</option>
+					<option value="gandi">Gandi</option>
+					<option value="namecheap">Namecheap</option>
+				</select>
+				<button type="submit" tabindex="1">Update</button>
+			</form>
+			{{ end }}
 			<ul>
 				{{ template "task" .Root.Subtasks }}
 			</ul>
diff --git a/core/installer/welcome/env.go b/core/installer/welcome/env.go
index 9dd2abc..7cc3c1a 100644
--- a/core/installer/welcome/env.go
+++ b/core/installer/welcome/env.go
@@ -43,18 +43,29 @@
 	ss            *soft.Client
 	repo          installer.RepoIO
 	nsCreator     installer.NamespaceCreator
+	dnsFetcher    installer.ZoneStatusFetcher
 	nameGenerator installer.NameGenerator
 	tasks         map[string]tasks.Task
+	dns           map[string]tasks.DNSZoneRef
 }
 
-func NewEnvServer(port int, ss *soft.Client, repo installer.RepoIO, nsCreator installer.NamespaceCreator, nameGenerator installer.NameGenerator) *EnvServer {
+func NewEnvServer(
+	port int,
+	ss *soft.Client,
+	repo installer.RepoIO,
+	nsCreator installer.NamespaceCreator,
+	dnsFetcher installer.ZoneStatusFetcher,
+	nameGenerator installer.NameGenerator,
+) *EnvServer {
 	return &EnvServer{
 		port,
 		ss,
 		repo,
 		nsCreator,
+		dnsFetcher,
 		nameGenerator,
 		make(map[string]tasks.Task),
+		make(map[string]tasks.DNSZoneRef),
 	}
 }
 
@@ -71,19 +82,37 @@
 
 func (s *EnvServer) monitorTask(w http.ResponseWriter, r *http.Request) {
 	vars := mux.Vars(r)
-	fmt.Printf("%+v %+v\n", s.tasks, vars)
-	t, ok := s.tasks[vars["key"]]
+	key, ok := vars["key"]
+	if !ok {
+		http.Error(w, "Task key not provided", http.StatusBadRequest)
+		return
+	}
+	t, ok := s.tasks[key]
 	if !ok {
 		http.Error(w, "Task not found", http.StatusBadRequest)
 		return
 	}
+	dnsRef, ok := s.dns[key]
+	if !ok {
+		http.Error(w, "Task dns configuration not found", http.StatusInternalServerError)
+		return
+	}
+	err, ready, records := s.dnsFetcher.Fetch(dnsRef.Namespace, dnsRef.Name)
+	// TODO(gio): check error type
+	if err != nil && (ready || len(records) > 0) {
+		panic("!! SHOULD NOT REACH !!")
+	}
+	if !ready && len(records) > 0 {
+		panic("!! SHOULD NOT REACH !!")
+	}
 	tmpl, err := htemplate.New("response").Parse(envCreatedHtml)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
 	if err := tmpl.Execute(w, map[string]any{
-		"Root": t,
+		"Root":       t,
+		"DNSRecords": records,
 	}); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
@@ -237,7 +266,7 @@
 	} else {
 		req.Name = name
 	}
-	t := tasks.NewCreateEnvTask(
+	t, dns := tasks.NewCreateEnvTask(
 		tasks.Env{
 			PCloudEnvName:  env.Name,
 			Name:           req.Name,
@@ -253,6 +282,7 @@
 		s.repo,
 	)
 	s.tasks["foo"] = t
+	s.dns["foo"] = dns
 	go t.Start()
 	http.Redirect(w, r, "/env/foo", http.StatusSeeOther)
 }