message:
ci: Add Packet ARM cluster
The cluster configuration is the same as for the existing
Packet cluster. The only difference is the server type
c(1|2).large.arm, the added variables os_arch/os_channel/ipxe_script_url,
and the worker count set to 1 instead of 2.

diff:
+module "controller" {
+ source = "../../packet/flatcar-linux/kubernetes"
+
+ providers = {
+ aws = aws.default
+ local = local.default
+ null = null.default
+ template = template.default
+ tls = tls.default
+ packet = packet.default
+ }
+
+ dns_zone = "$AWS_DNS_ZONE"
+ dns_zone_id = "$AWS_DNS_ZONE_ID"
+
+ ssh_keys = ["$PUB_KEY"]
+
+ asset_dir = pathexpand("~/assets")
+ cluster_name = "$CLUSTER_ID"
+ project_id = "$PACKET_PROJECT_ID"
+
+ facility = "sjc1"
+
+ controller_count = 1
+ controller_type = "c2.large.arm"
+ os_arch = "arm64"
+ os_channel = "alpha"
+ ipxe_script_url = "https://raw.githubusercontent.com/kinvolk/flatcar-ipxe-scripts/arm64-usr/packet.ipxe"
+
+ management_cidrs = [
+ "0.0.0.0/0", # Instances can be SSH-ed into from anywhere on the internet.
+ ]
+
+ node_private_cidr = "10.0.0.0/8"
+}
+
+module "worker-pool-1" {
+ source = "../../packet/flatcar-linux/kubernetes/workers"
+
+ providers = {
+ local = local.default
+ template = template.default
+ tls = tls.default
+ packet = packet.default
+ }
+
+
+ ssh_keys = ["$PUB_KEY"]
+
+ cluster_name = "$CLUSTER_ID"
+ project_id = "$PACKET_PROJECT_ID"
+
+ facility = "sjc1"
+ pool_name = "pool-1"
+
+ worker_count = 1
+ type = "c1.large.arm"
+ os_arch = "arm64"
+ os_channel = "alpha"
+ ipxe_script_url = "https://raw.githubusercontent.com/kinvolk/flatcar-ipxe-scripts/arm64-usr/packet.ipxe"
+
+ kubeconfig = module.controller.kubeconfig
+
+ labels = "node.supernova.io/role=backend"
+}

diff:
+provider "aws" {
+ version = "2.31.0"
+ alias = "default"
+}
+
+provider "ct" {
+ version = "0.4.0"
+}
+
+provider "local" {
+ version = "~> 1.2"
+ alias = "default"
+}
+
+provider "null" {
+ version = "~> 2.1"
+ alias = "default"
+}
+
+provider "template" {
+ version = "~> 2.1"
+ alias = "default"
+}
+
+provider "tls" {
+ version = "~> 2.0"
+ alias = "default"
+}
+
+provider "packet" {
+ version = "~> 2.7.3"
+ alias = "default"
+}


message: Makefile: Allow kube-hunter to be skipped

change_type: MODIFY

old_path: Makefile

new_path: Makefile

diff:
@@ -3,13 +3,17 @@ kubeconfig := $(KUBECONFIG)
ifeq ($(RUN_FROM_CI),"true")
kubeconfig := "${HOME}/assets/auth/kubeconfig"
endif
+kubehunter := ./scripts/kube-hunter.sh
+ifeq ($(SKIP_KUBE_HUNTER),"true")
+ kubehunter := echo
+endif
.PHONY: run-e2e-tests
run-e2e-tests: kube-hunter
KUBECONFIG=${kubeconfig} ./scripts/check-version-skew.sh
kube-hunter:
- KUBECONFIG=${kubeconfig} ./scripts/kube-hunter.sh
+ KUBECONFIG=${kubeconfig} ${kubehunter}
.PHONY: update-terraform-render-bootkube
update-terraform-render-bootkube:

license: Apache License 2.0

repo: kinvolk/lokomotive


message: scripts/check-version-skew.sh: Wait for cluster to be ready

diff:
@@ -19,6 +19,34 @@ function match_with_apiserver_version() {
fi
}
+readonly maxtries=200
+
+function check_tries() {
+ if [ "${count}" -gt "${maxtries}" ]; then
+ echo "Reached maximum number of retries."
+ echo "--------------------------------------"
+ echo "info dump:"
+ set -x
+ kubectl get pods,job
+ kubectl get events
+ kubectl logs "${pod_name}"
+ kubectl get "${pod_name}" -o yaml
+ set +x
+ echo "--------------------------------------"
+ exit 1
+ fi
+ count=$((count + 1))
+}
+
+# Wait until the cluster is responsive
+count=0
+until kubectl get nodes; do
+ check_tries
+
+ echo "Waiting for the cluster to be responsive..."
+ sleep 2
+done
+
echo "--------------------------------------"
echo "Testing version skew"
# find the apiserver version


message:
ci: Add AWS Flatcar Edge configuration
Tests on the Flatcar CL Edge channel should only
run on master branch changes. Therefore AWS is
chosen as the most reliable platform that always
has the current Edge release.

change_type: ADD

diff:
+../aws/aws-cluster.lokocfg.envsubst
\ No newline at end of file

diff:
+asset_dir = "~/lokoctl-assets"
+os_channel = "edge"

diff:
@@ -3,11 +3,16 @@ variable "asset_dir" {
type = "string"
}
+variable "os_channel" {
+ type = "string"
+}
+
cluster "aws" {
asset_dir = pathexpand(var.asset_dir)
cluster_name = "$CLUSTER_ID"
dns_zone = "$AWS_DNS_ZONE"
dns_zone_id = "$AWS_DNS_ZONE_ID"
+ os_channel = var.os_channel
ssh_pubkeys = ["$PUB_KEY"]
}

diff:
asset_dir = "~/lokoctl-assets"
+os_channel = "stable"


message:
Packet: Use iPXE file from the Flatcar release site
Point to the iPXE file that is generated as Flatcar
release output and uses relative URLs to refer to
the kernel and image.

diff:
@@ -17,7 +17,7 @@ cluster "packet" {
project_id = "$PACKET_PROJECT_ID"
- ipxe_script_url = "https://raw.githubusercontent.com/kinvolk/flatcar-ipxe-scripts/arm64-usr/packet.ipxe"
+ ipxe_script_url = "https://alpha.release.flatcar-linux.net/arm64-usr/current/flatcar_production_packet.ipxe"
os_arch = "arm64"
os_channel = "alpha"
controller_type = "c2.large.arm"
@@ -28,7 +28,7 @@ cluster "packet" {
worker_pool "pool-1" {
count = 1
- ipxe_script_url = "https://raw.githubusercontent.com/kinvolk/flatcar-ipxe-scripts/arm64-usr/packet.ipxe"
+ ipxe_script_url = "https://alpha.release.flatcar-linux.net/arm64-usr/current/flatcar_production_packet.ipxe"
os_arch = "arm64"
os_channel = "alpha"
node_type = "c2.large.arm"

diff:
@@ -252,7 +252,7 @@ module:
```
os_arch = "arm64"
os_channel = "alpha"
-ipxe_script_url = "https://raw.githubusercontent.com/kinvolk/flatcar-ipxe-scripts/arm64-usr/packet.ipxe"
+ipxe_script_url = "https://alpha.release.flatcar-linux.net/arm64-usr/current/flatcar_production_packet.ipxe"
```
The iPXE boot variable can be removed once Flatcar is available for


diff:
@@ -101,9 +101,6 @@ func (c *component) Metadata() components.Metadata {
Name: Name,
Namespace: k8sutil.Namespace{
Name: c.Namespace,
- Labels: map[string]string{
- "certmanager.k8s.io/disable-validation": "true",
- },
},
Helm: components.HelmMetadata{
// Cert-manager registers admission webhooks, so we should wait for the webhook to

original_message:
Remove a deprecated cert-manager namespace label

Signed-off-by: Maartje Eyskens <maartje@eyskens.me>


message:
docs: use new etcd service name and environment file
The etcd-member and drop-in file were used for the rkt-based etcd
service that is part of Flatcar.

diff:
@@ -48,9 +48,9 @@ Run the following commands:
export etcd_version=<latest etcd version e.g. v3.4.10>
sudo sed -i "s,IMAGE_TAG=.*,IMAGE_TAG=${etcd_version}\"," \
- /etc/systemd/system/etcd-member.service.d/40-etcd-cluster.conf
+ /etc/kubernetes/etcd.env
sudo systemctl daemon-reload
-sudo systemctl restart etcd-member
+sudo systemctl restart etcd
```
### Step 4: Verify update
@@ -58,14 +58,14 @@ sudo systemctl restart etcd-member
Verify that the etcd service is in `active (running)` state:
```bash
-sudo systemctl status --no-pager etcd-member
+sudo systemctl status --no-pager etcd
```
Run the following command to see logs of the process since the last restart:
```bash
sudo journalctl _SYSTEMD_INVOCATION_ID=$(sudo systemctl \
- show -p InvocationID --value etcd-member.service)
+ show -p InvocationID --value etcd.service)
```
> **NOTE**: Do not proceed with the update of the rest of the cluster if you encounter any errors.


message:
aws: fix wrong etcd settings
The rkt-based etcd-member service that is part of Flatcar used a unit
drop-in file but the new etcd service uses an environment file and
requires the folder to be set up with certain permissions.

diff:
@@ -52,7 +52,7 @@ systemd:
ExecStart=/bin/sh -c 'while ! /usr/bin/grep '^[^#[:space:]]' /etc/resolv.conf > /dev/null; do sleep 1; done'
[Install]
RequiredBy=kubelet.service
- RequiredBy=etcd-member.service
+ RequiredBy=etcd.service
- name: kubelet.service
enable: true
contents: |
@@ -211,7 +211,7 @@ storage:
# Rejoin a cluster as fresh node when etcd cannot join
# (e.g., after repovisioning, crashing or node being down).
# Set ExecStopPost=-/opt/etcd-rejoin to run when etcd failed and
- # use env vars of etcd-member.service.
+ # use env vars of etcd.service.
# Skip if not provisioned
if [ ! -d "/etc/ssl/etcd/" ]; then exit 0; fi
# or got stopped.
@@ -243,13 +243,14 @@ storage:
etcdctl member add "$ETCD_NAME" --peer-urls="$ETCD_INITIAL_ADVERTISE_PEER_URLS" $ARGS
# Join fresh without state
mv /var/lib/etcd "/var/lib/etcd-bkp-$(date +%s)" || true
- if [ -z "$(grep ETCD_INITIAL_CLUSTER_STATE=existing /etc/systemd/system/etcd-member.service.d/40-etcd-cluster.conf)" ]; then
- echo 'Environment="ETCD_INITIAL_CLUSTER_STATE=existing"' >> /etc/systemd/system/etcd-member.service.d/40-etcd-cluster.conf
+ install -m 700 -o etcd -g etcd -d /var/lib/etcd
+ if [ -z "$(grep ETCD_INITIAL_CLUSTER_STATE=existing /etc/kubernetes/etcd.env)" ]; then
+ echo ETCD_INITIAL_CLUSTER_STATE=existing >> /etc/kubernetes/etcd.env
# Apply change
systemctl daemon-reload
fi
# Restart unit (yes, within itself)
- systemctl restart etcd-member &
+ systemctl restart etcd &
- path: /etc/kubernetes/configure-kubelet-cgroup-driver
filesystem: root
mode: 0744


message:
packet: fix wrong etcd settings
The rkt-based etcd-member service that is part of Flatcar used a unit
drop-in	file but the new etcd service uses an environment file and
requires the folder to be set up with certain permissions.

diff:
@@ -47,7 +47,7 @@ systemd:
[Unit]
Description=Wait for DNS entries
Wants=systemd-resolved.service
- Before=kubelet.service etcd-member.service bootkube.service
+ Before=kubelet.service etcd.service bootkube.service
[Service]
Restart=on-failure
RestartSec=5s
@@ -55,16 +55,16 @@ systemd:
RemainAfterExit=true
ExecStart=/bin/sh -c 'while ! /usr/bin/grep '^[^#[:space:]]' /etc/resolv.conf > /dev/null; do sleep 1; done; /opt/wait-for-dns ${dns_zone} ${cluster_name}-private 3600'
[Install]
- RequiredBy=kubelet.service etcd-member.service bootkube.service
+ RequiredBy=kubelet.service etcd.service bootkube.service
- name: create-etcd-config.service
# This service will extract value of private interface from the env var file `/run/metadata/flatcar`.
# And then assign it to the variables that which will be stored in file `/etc/kubernetes/etcd.config`,
- # this file is sourced by etcd-member service.
+ # this file is sourced by etcd service.
enable: true
contents: |
[Unit]
Description=Create a etcd env file to be used by etcd to listen on private interface
- Before=etcd-member.service
+ Before=etcd.service
Requires=coreos-metadata.service
After=coreos-metadata.service
[Service]
@@ -73,7 +73,7 @@ systemd:
RemainAfterExit=true
ExecStart=/bin/sh -c 'echo "ETCD_LISTEN_CLIENT_URLS=https://$COREOS_PACKET_IPV4_PRIVATE_0:2379" > /etc/kubernetes/etcd.config && echo "ETCD_LISTEN_PEER_URLS=https://$COREOS_PACKET_IPV4_PRIVATE_0:2380" >> /etc/kubernetes/etcd.config && echo "ETCD_LISTEN_METRICS_URLS=http://$COREOS_PACKET_IPV4_PRIVATE_0:2381" >> /etc/kubernetes/etcd.config'
[Install]
- RequiredBy=etcd-member.service
+ RequiredBy=etcd.service
- name: coreos-metadata.service
enable: true
contents: |
@@ -265,7 +265,7 @@ storage:
# Rejoin a cluster as fresh node when etcd cannot join
# (e.g., after repovisioning, crashing or node being down).
# Set ExecStopPost=-/opt/etcd-rejoin to run when etcd failed and
- # use env vars of etcd-member.service.
+ # use env vars of etcd.service.
# Skip if not provisioned
if [ ! -d "/etc/ssl/etcd/" ]; then exit 0; fi
# or got stopped.
@@ -297,13 +297,14 @@ storage:
etcdctl member add "$ETCD_NAME" --peer-urls="$ETCD_INITIAL_ADVERTISE_PEER_URLS" $ARGS
# Join fresh without state
mv /var/lib/etcd "/var/lib/etcd-bkp-$(date +%s)" || true
- if [ -z "$(grep ETCD_INITIAL_CLUSTER_STATE=existing /etc/systemd/system/etcd-member.service.d/40-etcd-cluster.conf)" ]; then
- echo 'Environment="ETCD_INITIAL_CLUSTER_STATE=existing"' >> /etc/systemd/system/etcd-member.service.d/40-etcd-cluster.conf
+ install -m 700 -o etcd -g etcd -d /var/lib/etcd
+ if [ -z "$(grep ETCD_INITIAL_CLUSTER_STATE=existing /etc/kubernetes/etcd.env)" ]; then
+ echo ETCD_INITIAL_CLUSTER_STATE=existing >> /etc/kubernetes/etcd.env
# Apply change
systemctl daemon-reload
fi
# Restart unit (yes, within itself)
- systemctl restart etcd-member &
+ systemctl restart etcd &
- path: /var/lib/iptables/rules-save
filesystem: root
mode: 0644


message:
generic controller module: fix wrong etcd settings
The rkt-based etcd-member service that is part of Flatcar used a unit
drop-in	file but the new etcd service uses an environment file and
requires the folder to be set up with certain permissions.

diff:
@@ -82,7 +82,7 @@ storage:
# Rejoin a cluster as fresh node when etcd cannot join
# (e.g., after repovisioning, crashing or node being down).
# Set ExecStopPost=-/opt/etcd-rejoin to run when etcd failed and
- # use env vars of etcd-member.service.
+ # use env vars of etcd.service.
# Skip if not provisioned
if [ ! -d "/etc/ssl/etcd/" ]; then exit 0; fi
# or got stopped.
@@ -114,10 +114,11 @@ storage:
etcdctl member add "$ETCD_NAME" --peer-urls="$ETCD_INITIAL_ADVERTISE_PEER_URLS" $ARGS
# Join fresh without state
mv /var/lib/etcd "/var/lib/etcd-bkp-$(date +%s)" || true
- if [ -z "$(grep ETCD_INITIAL_CLUSTER_STATE=existing /etc/systemd/system/etcd-member.service.d/40-etcd-cluster.conf)" ]; then
- echo 'Environment="ETCD_INITIAL_CLUSTER_STATE=existing"' >> /etc/systemd/system/etcd-member.service.d/40-etcd-cluster.conf
+ install -m 700 -o etcd -g etcd -d /var/lib/etcd
+ if [ -z "$(grep ETCD_INITIAL_CLUSTER_STATE=existing /etc/kubernetes/etcd.env)" ]; then
+ echo ETCD_INITIAL_CLUSTER_STATE=existing >> /etc/kubernetes/etcd.env
# Apply change
systemctl daemon-reload
fi
# Restart unit (yes, within itself)
- systemctl restart etcd-member &
+ systemctl restart etcd &


diff:
@@ -286,3 +286,19 @@ current_version=$(grep -A1 'poseidon/matchbox' pkg/platform/baremetal/template.g
get_latest_release poseidon/terraform-provider-matchbox
printf "${format}" "Matchbox" "${current_version}" "${version}"
+
+###########################
+# TLS Provider
+cd "${workdir}"
+current_version=$(grep -A1 'hashicorp/tls' assets/terraform-modules/bootkube/versions.tf | tail -1 | cut -d"\"" -f2 | sed 's|~>||g' | sed 's| ||g')
+
+get_latest_release hashicorp/terraform-provider-tls
+printf "${format}" "TLS" "${current_version}" "${version}"
+
+###########################
+# Template Provider
+cd "${workdir}"
+current_version=$(grep -A1 'hashicorp/template' assets/terraform-modules/bootkube/versions.tf | tail -1 | cut -d"\"" -f2 | sed 's|~>||g' | sed 's| ||g')
+
+get_latest_release hashicorp/terraform-provider-template
+printf "${format}" "Template" "${current_version}" "${version}"

original_message:
Add TLS and Template providers to find-updates.sh

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -6,7 +6,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
- version = "3.12.0"
+ version = "3.33.0"
}
ct = {
source = "poseidon/ct"

diff:
@@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
- version = "3.12.0"
+ version = "3.33.0"
}
}
}

original_message:
Update Hashicorp AWS Terraform Provider to v0.33.0

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -10,7 +10,7 @@ terraform {
}
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
null = {
source = "hashicorp/null"

diff:
@@ -10,7 +10,7 @@ terraform {
}
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
template = {
source = "hashicorp/template"

diff:
@@ -6,7 +6,7 @@ terraform {
required_providers {
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
azurerm = {
source = "hashicorp/azurerm"

diff:
@@ -4,7 +4,7 @@ terraform {
required_providers {
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
azurerm = {
source = "hashicorp/azurerm"

diff:
@@ -6,7 +6,7 @@ terraform {
required_providers {
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
null = {
source = "hashicorp/null"

diff:
@@ -4,7 +4,7 @@ terraform {
required_providers {
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
template = {
source = "hashicorp/template"

diff:
@@ -4,7 +4,7 @@ terraform {
required_providers {
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
random = {
source = "hashicorp/random"

diff:
@@ -6,7 +6,7 @@ terraform {
required_providers {
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
local = {
source = "hashicorp/local"

diff:
@@ -6,7 +6,7 @@ terraform {
required_providers {
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
packet = {
source = "packethost/packet"

diff:
@@ -8,7 +8,7 @@ terraform {
}
ct = {
source = "poseidon/ct"
- version = "0.7.1"
+ version = "0.8.0"
}
}
}

original_message:
Update Poseidon CT Terraform Provider to v0.8.0

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -5,7 +5,7 @@ terraform {
required_providers {
local = {
source = "hashicorp/local"
- version = "2.0.0"
+ version = "2.1.0"
}
template = {
source = "hashicorp/template"

diff:
@@ -10,7 +10,7 @@ terraform {
}
local = {
source = "hashicorp/local"
- version = "2.0.0"
+ version = "2.1.0"
}
null = {
source = "hashicorp/null"

diff:
@@ -66,7 +66,7 @@ terraform {
}
local = {
source = "hashicorp/local"
- version = "2.0.0"
+ version = "2.1.0"
}
{{- if .ApplicationName }}
azuread = {

original_message:
Update Hashicorp Local Terraform Provider to v2.1.0

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -10,7 +10,7 @@ terraform {
}
azurerm = {
source = "hashicorp/azurerm"
- version = "2.41.0"
+ version = "2.52.0"
}
null = {
source = "hashicorp/null"

diff:
@@ -8,7 +8,7 @@ terraform {
}
azurerm = {
source = "hashicorp/azurerm"
- version = "2.41.0"
+ version = "2.52.0"
}
template = {
source = "hashicorp/template"

diff:
@@ -62,7 +62,7 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
- version = "2.41.0"
+ version = "2.52.0"
}
local = {
source = "hashicorp/local"

original_message:
Update Azure Terraform Provider to v2.52.0

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -24,7 +24,7 @@ spec:
serviceAccountName: dex
initContainers:
- name: download-theme
- image: alpine/git:v2.24.3
+ image: alpine/git:v2.30.1
command:
- git
- clone

original_message:
Use new version of apline/git in Dex

This uses the latest alpine/git image to deploy Dex. This release added
ARM64 support which stops Dex from breaking when deploying it on ARM64.

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -23,7 +23,6 @@ cert-manager component configuration example:
component "cert-manager" {
email = "example@example.com"
namespace = "cert-manager"
- webhooks = false
}
```
@@ -35,7 +34,6 @@ Table of all the arguments accepted by the component.
|-------------------|----------------------------------------------------------------|:------------:|:------:|:--------:|
| `email` | Email used for certificates to receive expiry notifications. | - | string | true |
| `namespace` | Namespace to deploy the cert-manager into. | cert-manager | string | false |
-| `webhooks` | Controls if webhooks should be deployed. | true | bool | false |
| `service_monitor` | Specifies how metrics can be retrieved from a set of services. | false | bool | false |

diff:
@@ -35,7 +35,6 @@ const (
type component struct {
Email string `hcl:"email,attr"`
Namespace string `hcl:"namespace,optional"`
- Webhooks bool `hcl:"webhooks,optional"`
ServiceMonitor bool `hcl:"service_monitor,optional"`
}
@@ -45,15 +44,12 @@ type component struct {
func NewConfig() *component {
return &component{
Namespace: "cert-manager",
- Webhooks: true,
ServiceMonitor: false,
}
}
const chartValuesTmpl = `
email: {{.Email}}
-webhook:
- enabled: {{.Webhooks}}
{{ if .ServiceMonitor }}
prometheus:
servicemonitor:
@@ -103,7 +99,7 @@ func (c *component) Metadata() components.Metadata {
Name: c.Namespace,
},
Helm: components.HelmMetadata{
- // Cert-manager registers admission webhooks, so we should wait for the webhook to
+ // cert-manager registers admission webhooks, so we should wait for the webhook to
// become ready before proceeding with installing other components, as it may fail.
// If webhooks are registered with 'failurePolicy: Fail', then kube-apiserver will reject
// creating objects requiring the webhook until the webhook itself becomes ready. So if the

original_message:
Remove the Webhook settiing of cert-manager

The no-webhook version was removed since 0.15, this flag became
non functional since then and will always install the webhook

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -93,3 +93,20 @@ git checkout openebs/crds/storagepoolclaims.yaml
- Installation instructions: https://openebs.github.io/charts/.
- More information about the chart: https://github.com/openebs/charts.
- Code repository: https://github.com/openebs/openebs.
+
+## Prometheus operator
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf prometheus-operator
+helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
+helm repo update
+helm fetch --untar --untardir ./ prometheus-community/kube-prometheus-stack
+mv kube-prometheus-stack prometheus-operator
+```
+
+- Installation instructions: https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack.
+- Code repository: https://github.com/prometheus-operator/kube-prometheus.
+

original_message:
Add upgrade instructions for the Prometheus operator chart

This adds step by step instructions to contributors on how to update the
 Prometheus operator chart in assets

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -201,10 +201,10 @@ component "prometheus-operator" {
providers:
- name: 'sidecarProvider'
orgId: 1
- folder: ''
type: file
disableDeletion: false
allowUiUpdates: false
+ updateIntervalSeconds: 30
options:
foldersFromFilesStructure: true
path: /tmp/dashboards`,

original_message:
Fix component_test.go to have latest prometheus config

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -62,6 +62,7 @@ type config struct {
DownloadProtocol string `hcl:"download_protocol,optional"`
NetworkIPAutodetectionMethod string `hcl:"network_ip_autodetection_method,optional"`
CLCSnippets map[string][]string `hcl:"clc_snippets,optional"`
+ CertsValidityPeriodHours int `hcl:"certs_validity_period_hours,optional"`
KubeAPIServerExtraFlags []string
}
@@ -235,6 +236,7 @@ func createTerraformConfigFile(cfg *config, terraformPath string) error {
Labels map[string]string
EncryptPodTraffic bool
IgnoreX509CNCheck bool
+ CertsValidityPeriodHours int
ConntrackMaxPerCore int
InstallDisk string
InstallToSmallestDisk bool
@@ -266,6 +268,7 @@ func createTerraformConfigFile(cfg *config, terraformPath string) error {
Labels: cfg.Labels,
EncryptPodTraffic: cfg.EncryptPodTraffic,
IgnoreX509CNCheck: cfg.IgnoreX509CNCheck,
+ CertsValidityPeriodHours: cfg.CertsValidityPeriodHours,
ConntrackMaxPerCore: cfg.ConntrackMaxPerCore,
InstallDisk: cfg.InstallDisk,
InstallToSmallestDisk: cfg.InstallToSmallestDisk,

diff:
@@ -68,6 +68,10 @@ module "bare-metal-{{.ClusterName}}" {
ignore_x509_cn_check = {{.IgnoreX509CNCheck}}
conntrack_max_per_core = {{.ConntrackMaxPerCore}}
+ {{- if .CertsValidityPeriodHours }}
+ certs_validity_period_hours = {{.CertsValidityPeriodHours}}
+ {{- end }}
+
{{- if .InstallDisk }}
install_disk = "{{ .InstallDisk }}"
{{- end }}

original_message:
baremetal: add certs_validity_period_hours to bare-metal

This exposes the certs_validity_period_hours option to the bare-metal
module in lokocfg

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -101,7 +101,8 @@ run-e2e-tests:
KUBECONFIG=${kubeconfig} PLATFORM=${platform} go test -mod=$(MOD) -tags="$(platform),poste2e" -covermode=atomic -buildmode=exe -v -count=1 -timeout=17m ./test/...
# This is a test that should be run in the end to reduce the disruption to other tests because
# it will delete a node.
- KUBECONFIG=${kubeconfig} PLATFORM=${platform} go test -mod=$(MOD) -tags="$(platform),disruptivee2e" -covermode=atomic -buildmode=exe -v -count=1 ./test/...
+ # The timeout is made longer as it will perform actions that will take longer than the default 10 minutes.
+ KUBECONFIG=${kubeconfig} PLATFORM=${platform} go test -timeout 30m -mod=$(MOD) -tags="$(platform),disruptivee2e" -covermode=atomic -buildmode=exe -v -count=1 ./test/...
.PHONY: all
all: build test

diff:
@@ -93,6 +93,7 @@ resource_dir=$(pwd)/..
cd "ci/$platform"
cat "$platform-cluster.lokocfg.envsubst" | envsubst '$AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY $PUB_KEY $CLUSTER_ID $AWS_DEFAULT_REGION $AWS_DNS_ZONE $AWS_DNS_ZONE_ID $PACKET_PROJECT_ID $EMAIL $GITHUB_CLIENT_ID $GITHUB_CLIENT_SECRET $DEX_STATIC_CLIENT_CLUSTERAUTH_ID $DEX_STATIC_CLIENT_CLUSTERAUTH_SECRET $GANGWAY_REDIRECT_URL $GANGWAY_SESSION_KEY $DEX_INGRESS_HOST $GANGWAY_INGRESS_HOST $ISSUER_HOST $REDIRECT_URI $API_SERVER_URL $AUTHORIZE_URL $TOKEN_URL $PACKET_LOCATION $ARM_SUBSCRIPTION_ID $ARM_TENANT_ID $ARM_CLIENT_ID $ARM_CLIENT_SECRET' >"$platform-cluster.lokocfg"
+export LOKOCFG_LOCATION="$(pwd)/$platform-cluster.lokocfg"
export KUBECONFIG=$HOME/lokoctl-assets/cluster-assets/auth/kubeconfig
echo "export KUBECONFIG=$KUBECONFIG" >> ~/.bashrc

diff:
+// Copyright 2021 The Lokomotive Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build packet baremetal aws
+// +build disruptivee2e
+
+package kubernetes_test
+
+import (
+ "bytes"
+ "crypto/tls"
+ "crypto/x509"
+ "net/http"
+ "os"
+ "path"
+ "strings"
+ "testing"
+
+ log "github.com/sirupsen/logrus"
+
+ "github.com/kinvolk/lokomotive/cli/cmd/cluster"
+ testutil "github.com/kinvolk/lokomotive/test/components/util"
+)
+
+func TestCertificateRotate(t *testing.T) { //nolint:funlen
+ contextLogger := log.WithFields(log.Fields{
+ "command": "TestCertificateRotate",
+ })
+
+ oldConfig := testutil.BuildKubeConfig(t)
+
+ oldCerts := fetchCertificatesForEndpoint(t, oldConfig.Host)
+
+ cfgPath := testutil.LokocfgPath(t)
+ dir, _ := path.Split(cfgPath)
+
+ // We will be changing directories for relative paths in lokocfg to function.
+ // This will revert it back when this test exits.
+ testDir, err := os.Getwd()
+ if err != nil {
+ t.Fatalf("Getting current work directory failed: %v", err)
+ }
+
+ t.Cleanup(func() {
+ if err := os.Chdir(testDir); err != nil {
+ t.Fatalf("Failed to change back %q: %v", testDir, err)
+ }
+ })
+
+ if err := os.Chdir(dir); err != nil {
+ t.Fatalf("Changing work directory failed: %v", err)
+ }
+
+ options := cluster.CertificateRotateOptions{
+ Confirm: true,
+ Verbose: true,
+ ConfigPath: cfgPath,
+ ValuesPath: path.Join(dir, "lokocfg.vars"),
+ }
+
+ if err := cluster.RotateCertificates(contextLogger, options); err != nil {
+ t.Fatalf("Rotating Certificates failed: %v", err)
+ }
+
+ newConfig := testutil.BuildKubeConfig(t)
+
+ if bytes.Equal(oldConfig.CAData, newConfig.CAData) {
+ t.Fatal("CA Certificate is identical after rotation")
+ }
+
+ client := testutil.CreateKubeClient(t)
+
+ // Test if all kubelets are running.
+ namespace := "kube-system"
+ daemonset := "kubelet"
+
+ t.Run("leaves_all_self_hosted_kubelets_running", func(t *testing.T) {
+ testutil.WaitForDaemonSet(t, client, namespace, daemonset, testutil.RetryInterval, testutil.Timeout)
+
+ newCerts := fetchCertificatesForEndpoint(t, oldConfig.Host)
+
+ // Currently Lokomotive doesn't use intermediate CAs, thus we can safely assume the first one is the leaf cert.
+ if oldCerts[0].NotAfter.After(newCerts[0].NotAfter) || oldCerts[0].NotAfter.Equal(newCerts[0].NotAfter) {
+ t.Fatalf("Incorrect not after time on new certificate: %v is equal or before %v",
+ newCerts[0].NotAfter, oldCerts[0].NotAfter)
+ }
+ })
+}
+
+func fetchCertificatesForEndpoint(t *testing.T, url string) []*x509.Certificate {
+ if !strings.HasPrefix(url, "https://") {
+ url = "https://" + url
+ }
+
+ /* #nosec G402*/
+ tr := &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ }
+ client := &http.Client{Transport: tr}
+
+ resp, err := client.Get(url) //nolint:noctx
+ if err != nil {
+ t.Fatalf("Getting url %q: %v", url, err)
+ }
+
+ t.Cleanup(func() {
+ if err := resp.Body.Close(); err != nil {
+ t.Fatalf("Failed to close response body: %v", err)
+ }
+ })
+
+ if len(resp.TLS.PeerCertificates) < 1 {
+ t.Fatalf("No certificates offered in TLS handshake")
+ }
+
+ return resp.TLS.PeerCertificates
+}

diff:
@@ -87,10 +87,10 @@ func Kubeconfig(t *testing.T) []byte {
return k
}
-// buildKubeConfig reads the environment variable KUBECONFIG and then builds the rest client config
+// BuildKubeConfig reads the environment variable KUBECONFIG and then builds the rest client config
// object which can be either used to create kube client to talk to apiserver or to just read the
// kubeconfig data.
-func buildKubeConfig(t *testing.T) *restclient.Config {
+func BuildKubeConfig(t *testing.T) *restclient.Config {
kubeconfig := KubeconfigPath(t)
t.Logf("using KUBECONFIG=%s", kubeconfig)
@@ -105,7 +105,7 @@ func buildKubeConfig(t *testing.T) *restclient.Config {
// CreateKubeClient returns a kubernetes client reading the KUBECONFIG environment variable.
func CreateKubeClient(t *testing.T) *kubernetes.Clientset {
- cs, err := kubernetes.NewForConfig(buildKubeConfig(t))
+ cs, err := kubernetes.NewForConfig(BuildKubeConfig(t))
if err != nil {
t.Fatalf("failed creating new clientset: %v", err)
}
@@ -392,7 +392,7 @@ func (p *PortForwardInfo) CloseChan() {
// p.WaitUntilForwardingAvailable(t)
//
func (p *PortForwardInfo) PortForward(t *testing.T) {
- config := buildKubeConfig(t)
+ config := BuildKubeConfig(t)
roundTripper, upgrader, err := spdy.RoundTripperFor(config)
if err != nil {

original_message:
test: add e2e tests for cert rotation

This adds an e2e test that rotates the certificates then checks:
* if all kubelets are up
* the kubeconfig got changed
* the API serves a longer valid cert

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message:
cli/cmd/cluster: allow to skip the control plane update
When the cluster is not fully set up and lokoctl is run again to fix that
problem, the user may want to avoid the control plane update happen at the
same time, because it can cause issues.

diff:
@@ -26,6 +26,7 @@ var (
verbose bool
skipComponents bool
skipPreUpdateHealthCheck bool
+ skipControlPlaneUpdate bool
upgradeKubelets bool
)
@@ -47,6 +48,8 @@ func init() {
pf.BoolVarP(&skipPreUpdateHealthCheck, "skip-pre-update-health-check", "", false,
"Skip ensuring that cluster is healthy before updating (not recommended)")
+ pf.BoolVarP(&skipControlPlaneUpdate, "skip-control-plane-update", "", false,
+ "Skip updating the control plane (not recommended)")
pf.BoolVarP(&upgradeKubelets, "upgrade-kubelets", "", false, "Experimentally upgrade self-hosted kubelets")
}
@@ -62,6 +65,7 @@ func runClusterApply(cmd *cobra.Command, args []string) {
UpgradeKubelets: upgradeKubelets,
SkipComponents: skipComponents,
SkipPreUpdateHealthCheck: skipPreUpdateHealthCheck,
+ SkipControlPlaneUpdate: skipControlPlaneUpdate,
Verbose: verbose,
ConfigPath: viper.GetString("lokocfg"),
ValuesPath: viper.GetString("lokocfg-vars"),

diff:
@@ -31,6 +31,7 @@ type ApplyOptions struct {
UpgradeKubelets bool
SkipComponents bool
SkipPreUpdateHealthCheck bool
+ SkipControlPlaneUpdate bool
Verbose bool
ConfigPath string
ValuesPath string
@@ -126,7 +127,7 @@ func Apply(contextLogger *log.Entry, options ApplyOptions) error {
}
// Do controlplane upgrades only if cluster already exists and it is not a managed platform.
- if exists && !c.platform.Meta().Managed {
+ if exists && !options.SkipControlPlaneUpdate && !c.platform.Meta().Managed {
fmt.Printf("\nEnsuring that cluster controlplane is up to date.\n")
if err := c.upgradeControlPlane(contextLogger, kubeconfig); err != nil {


message:
baremetal: use grub.cfg file for kernel arguments
While the kernel arguments can be set for PXE, they have not been
applied to the final installation.
Use the /usr/share/oem/grub.cfg file to permanently set the kernel
arguments, so that on each boot the final installation uses the
kernel arguments provided by the user.

diff:
@@ -27,6 +27,7 @@ resource "matchbox_profile" "flatcar-install" {
container_linux_oem = var.container_linux_oem
ssh_keys = jsonencode(var.ssh_keys)
install_to_smallest_disk = var.install_to_smallest_disk
+ kernel_args = join(" ", var.kernel_args)
# only cached-container-linux profile adds -b baseurl
baseurl_flag = ""
})
@@ -63,6 +64,7 @@ resource "matchbox_profile" "cached-flatcar-linux-install" {
container_linux_oem = var.container_linux_oem
ssh_keys = jsonencode(var.ssh_keys)
install_to_smallest_disk = var.install_to_smallest_disk
+ kernel_args = join(" ", var.kernel_args)
# profile uses -b baseurl to install from matchbox cache
baseurl_flag = "-b ${var.http_endpoint}/assets/flatcar"
})

diff:
@@ -30,6 +30,8 @@ storage:
contents:
inline: |
#!/bin/bash -ex
+ # unmount any leftovers at the beginning before we modify the disk the mount uses
+ umount /tmp/oemfs || true
curl --retry 10 "${ignition_endpoint}?{{.request.raw_query}}&os=installed" -o ignition.json
flatcar-install \
%{~ if install_to_smallest_disk ~}
@@ -43,6 +45,12 @@ storage:
${baseurl_flag} \
-i ignition.json
udevadm settle
+ OEM_DEV="$(blkid -t "LABEL=OEM" -o device)"
+ mkdir -p /tmp/oemfs
+ mount "$${OEM_DEV}" /tmp/oemfs
+ # append to file on newly created partition, do not remove the defaults
+ echo 'set linux_append="${kernel_args}"' >> /tmp/oemfs/grub.cfg
+ umount /tmp/oemfs
systemctl reboot
passwd:
users:

diff:
@@ -41,7 +41,7 @@ variable "container_linux_oem" {
variable "kernel_args" {
type = list(string)
- description = "Additional kernel arguments to provide at PXE boot."
+ description = "Additional kernel arguments to provide at PXE boot and in /usr/share/oem/grub.cfg."
default = []
}

diff:
@@ -190,7 +190,7 @@ os_version = var.custom_default_os_version
| `ignore_x509_cn_check` | Ignore check of common name in x509 certificates. If any application is built pre golang 1.15 then API server rejects x509 from such application, enable this to get around apiserver. | false | bool | false |
| `install_to_smallest_disk` | Installs Flatcar Container Linux to the smallest disk. | false | bool | false |
| `install_disk` | Disk device where Flatcar Container Linux should be installed. | "/dev/sda" | string | false |
-| `kernel_args` | Additional kernel args to provide at PXE boot. | ["kvm-intel.nested=1"] | list(string) | false |
+| `kernel_args` | Additional kernel args to provide at PXE boot and in /usr/share/oem/grub.cfg. | [] | list(string) | false |
| `download_protocol` | Protocol iPXE uses to download the kernel and initrd. iPXE must be compiled with crypto support for https. Unused if `cached_install` is true. Use `http` if the iPXE boot using `https` is slow or does not work due to SSL settings. | "https" | string | false |
| `network_ip_autodetection_method` | Method to detect host IPv4 address. Accepted values include 'first-found', 'can-reach=<DESTINATION>', 'interface=<INTERFACE-REGEX>', 'skip-interface=<INTERFACE-REGEX>, 'cidr=<CIDR>'. | "first-found" | string | false |
| `oidc` | OIDC configuration block. | - | object | false |


message: Document how to update external-dns

diff:
@@ -110,3 +110,16 @@ mv kube-prometheus-stack prometheus-operator
- Installation instructions: https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack.
- Code repository: https://github.com/prometheus-operator/kube-prometheus.
+## external-dns
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf external-dns
+helm repo add bitnami https://charts.bitnami.com/bitnami
+helm repo update
+helm fetch --untar --untardir ./ bitnami/external-dns
+```
+
+- Chart location: https://github.com/bitnami/charts/tree/master/bitnami/external-dns.

original_message:
Document how to update external-dns

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message:
baremetal: let installer.service retry on failure
In case the network only has a temporary problem, the installer service
should start again on failure.
Convert it to a oneshot service to set RemainAfterExist, so that it is
not triggered twice if anything that depends on it is pulling it in
again after it finished.

diff:
@@ -8,7 +8,10 @@ systemd:
Requires=network-online.target
After=network-online.target
[Service]
- Type=simple
+ Type=oneshot
+ RemainAfterExit=true
+ Restart=on-failure
+ RestartSec=10s
ExecStart=/opt/installer
[Install]
WantedBy=multi-user.target


message:
pkg/terraform: increase the default parallelism
The default of 10 parallel steps does not limit creation of a small
cluster but on a cluster with more than 10 nodes it leads to creation in
sequential batches of 10, slowing the bring up down.

diff:
@@ -292,7 +292,7 @@ func (c *config) Apply(ex *terraform.Executor) error {
return err
}
- return ex.Apply(nil)
+ return ex.Apply([]string{terraform.WithParallelism})
}
// ApplyWithoutParallel applies Terraform configuration without parallel execution.
@@ -301,7 +301,7 @@ func (c *config) ApplyWithoutParallel(ex *terraform.Executor) error {
return fmt.Errorf("initializing Terraform configuration: %w", err)
}
- return ex.Apply([]string{"-parallelism=1"})
+ return ex.Apply([]string{terraform.WithoutParallelism})
}
// Destroy destroys AKS infrastructure via Terraform.

diff:
@@ -140,7 +140,7 @@ func (c *config) Apply(ex *terraform.Executor) error {
return err
}
- return ex.Apply(nil)
+ return ex.Apply([]string{terraform.WithParallelism})
}
// ApplyWithoutParallel applies Terraform configuration without parallel execution.
@@ -149,7 +149,7 @@ func (c *config) ApplyWithoutParallel(ex *terraform.Executor) error {
return fmt.Errorf("initializing Terraform configuration: %w", err)
}
- return ex.Apply([]string{"-parallelism=1"})
+ return ex.Apply([]string{terraform.WithoutParallelism})
}
func (c *config) Destroy(ex *terraform.Executor) error {

diff:
@@ -117,7 +117,7 @@ func (c *config) Apply(ex *terraform.Executor) error {
return err
}
- return ex.Apply(nil)
+ return ex.Apply([]string{terraform.WithParallelism})
}
// ApplyWithoutParallel applies Terraform configuration without parallel execution.
@@ -126,7 +126,7 @@ func (c *config) ApplyWithoutParallel(ex *terraform.Executor) error {
return fmt.Errorf("initializing Terraform configuration: %w", err)
}
- return ex.Apply([]string{"-parallelism=1"})
+ return ex.Apply([]string{terraform.WithoutParallelism})
}
func (c *config) Destroy(ex *terraform.Executor) error {

diff:
@@ -215,7 +215,7 @@ func (c *config) Apply(ex *terraform.Executor) error {
return err
}
- return c.terraformSmartApply(ex, c.DNS, nil)
+ return c.terraformSmartApply(ex, c.DNS, []string{terraform.WithParallelism})
}
// ApplyWithoutParallel applies Terraform configuration without parallel execution.
@@ -224,7 +224,7 @@ func (c *config) ApplyWithoutParallel(ex *terraform.Executor) error {
return fmt.Errorf("initializing Terraform configuration: %w", err)
}
- return c.terraformSmartApply(ex, c.DNS, []string{"-parallelism=1"})
+ return c.terraformSmartApply(ex, c.DNS, []string{terraform.WithoutParallelism})
}
func (c *config) Destroy(ex *terraform.Executor) error {

diff:
@@ -162,7 +162,7 @@ func (c *Config) Apply(ex *terraform.Executor) error {
return err
}
- return ex.Apply(nil)
+ return ex.Apply([]string{terraform.WithParallelism})
}
// ApplyWithoutParallel applies Terraform configuration without parallel executions.
@@ -171,7 +171,7 @@ func (c *Config) ApplyWithoutParallel(ex *terraform.Executor) error {
return fmt.Errorf("initializing Terraform configuration: %w", err)
}
- return ex.Apply([]string{"-parallelism=1"})
+ return ex.Apply([]string{terraform.WithoutParallelism})
}
// Destroy destroys Terraform managed resources.

diff:
@@ -46,6 +46,11 @@ const (
requiredVersion = ">= 0.13, < 0.14"
noOfLinesOnError = 20
+
+ // WithoutParallelism sets the parallelism value to 1.
+ WithoutParallelism = "-parallelism=1"
+ // WithParallelism sets the parallelism value to 100.
+ WithParallelism = "-parallelism=100"
)
// ErrBinaryNotFound denotes the fact that the Terraform binary could not be


message:
baremetal: sets hostname controller_names/worker_names
Sets the hostname from the `<cluster_name>-worker-<count_index>` which
is set when `set_standard_hostname` is true, to
`controller_names<count_index>` for controllers and
`worker_names<count_index>` for workers
The hostname change got introduced by where it was set from the
template variable `domain_name` coming from
var.controller_domains[count.index]

diff:
@@ -10,6 +10,17 @@ module "controller" {
apiserver = format("%s.%s", var.cluster_name, var.k8s_domain_name)
ca_cert = module.bootkube.ca_cert
kubelet_labels = lookup(var.node_specific_labels, var.controller_names[count.index], {})
- clc_snippets = lookup(var.clc_snippets, var.controller_names[count.index], [])
- set_standard_hostname = true
+ set_standard_hostname = false
+ clc_snippets = concat(lookup(var.clc_snippets, var.controller_names[count.index], []), [
+ <<EOF
+storage:
+ files:
+ - path: /etc/hostname
+ filesystem: root
+ mode: 0644
+ contents:
+ inline: ${var.controller_names[count.index]}
+EOF
+ ,
+ ])
}

diff:
@@ -9,7 +9,18 @@ module "worker" {
apiserver = format("%s.%s", var.cluster_name, var.k8s_domain_name)
kubelet_labels = merge(lookup(var.node_specific_labels, var.worker_names[count.index], {}), var.labels)
cluster_name = var.cluster_name
- clc_snippets = lookup(var.clc_snippets, var.worker_names[count.index], [])
- set_standard_hostname = true
+ set_standard_hostname = false
+ clc_snippets = concat(lookup(var.clc_snippets, var.worker_names[count.index], []), [
+ <<EOF
+storage:
+ files:
+ - path: /etc/hostname
+ filesystem: root
+ mode: 0644
+ contents:
+ inline: ${var.worker_names[count.index]}
+EOF
+ ,
+ ])
}

original_message:
baremetal: sets hostname controller_names/worker_names

Sets the hostname from the `<cluster_name>-worker-<count_index>` which
is set when `set_standard_hostname` is true, to
`controller_names<count_index>` for controllers and
`worker_names<count_index>` for workers

The hostname change got introduced by #1477 where it was set from the
template variable `domain_name` coming from
var.controller_domains[count.index]


diff:
@@ -44,22 +44,35 @@ Update helm chart in `assets/charts/control-plane/calico` after comparing it wit
- Releases: https://github.com/projectcalico/calico/releases.
-## Cert Manager
+## cert-manager
Run the following commands in the root of this repository:
```bash
-cd assets/components/cert-manager
+cd assets/charts/components/
helm repo add jetstack https://charts.jetstack.io
helm repo update
-rm -rf manifests
+rm -rf cert-manager
helm fetch --untar --untardir ./ jetstack/cert-manager
-mv cert-manager manifests
-git checkout ./manifests/templates/letsencrypt-clusterissuer-prod.yaml
-git checkout ./manifests/templates/letsencrypt-clusterissuer-staging.yaml
-git checkout ./manifests/templates/namespace.yaml
+git checkout ./cert-manager/templates/letsencrypt-clusterissuer-prod.yaml
+git checkout ./cert-manager/templates/letsencrypt-clusterissuer-staging.yaml
+git checkout ./cert-manager/templates/namespace.yaml
+```
+
+Run the following command one at a time and see if the Lokomotive specific changes are not
+overridden:
+
+```
+git diff ./cert-manager/templates/psp.yaml
+git checkout ./cert-manager/templates/psp.yaml
+
+git diff ./cert-manager/templates/cainjector-psp.yaml
+git checkout ./cert-manager/templates/cainjector-psp.yaml
+
+git diff ./cert-manager/templates/webhook-psp.yaml
+git checkout ./cert-manager/templates/webhook-psp.yaml
```
- Releases: https://github.com/jetstack/cert-manager/releases.

original_message:
Correct the cert-manager update instructions

They seem to have gotten out of date and refering to an older file
structure. This makes them correct again. As well as fixes the spelling
of cert-manager.

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -136,3 +136,22 @@ helm fetch --untar --untardir ./ bitnami/external-dns
```
- Chart location: https://github.com/bitnami/charts/tree/master/bitnami/external-dns.
+
+## aws-ebs-csi-driver
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf aws-ebs-csi-driver
+helm repo add aws-ebs-csi-driver https://kubernetes-sigs.github.io/aws-ebs-csi-driver
+helm repo update
+helm fetch --untar --untardir ./ aws-ebs-csi-driver/aws-ebs-csi-driver
+git checkout aws-ebs-csi-driver/templates/networkpolicy.yaml
+git checkout aws-ebs-csi-driver/templates/volumesnapshotclass.yaml
+git checkout aws-ebs-csi-driver/crds
+```
+
+Update the CRDs by following the changes in this [upstream CRD config](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/deploy/kubernetes/cluster/crd_snapshotter.yaml).
+
+- Code repository: https://github.com/kubernetes-sigs/aws-ebs-csi-driver.

original_message:
Add update instructions for aws-ebs-csi-driver

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message: Document how to update Velero

diff:
@@ -155,3 +155,17 @@ git checkout aws-ebs-csi-driver/crds
Update the CRDs by following the changes in this [upstream CRD config](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/deploy/kubernetes/cluster/crd_snapshotter.yaml).
- Code repository: https://github.com/kubernetes-sigs/aws-ebs-csi-driver.
+
+## velero
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf velero
+helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
+helm repo update
+helm fetch --untar --untardir ./ vmware-tanzu/velero
+```
+
+- Chart location: https://github.com/vmware-tanzu/helm-charts/tree/main/charts/velero

original_message:
Document how to update Velero

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message: Update the OpenEBS update instructions

diff:
@@ -95,12 +95,13 @@ helm fetch --untar --untardir ./ stable/metrics-server
Run the following commands in the root of this repository:
```bash
-cd assets/components
-rm -rf openebs
+cd assets/charts/components
+rm -rf openebs-operator
helm repo add openebs https://openebs.github.io/charts
helm repo update
helm fetch --untar --untardir ./ openebs/openebs
-git checkout openebs/crds/storagepoolclaims.yaml
+mv openebs openebs-operator
+git checkout openebs-operator/crds/storagepoolclaims.yaml
```
- Installation instructions: https://openebs.github.io/charts/.

original_message:
Update the OpenEBS update instructions

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message: Document updating node-problem-detector

diff:
@@ -170,3 +170,17 @@ helm fetch --untar --untardir ./ vmware-tanzu/velero
```
- Chart location: https://github.com/vmware-tanzu/helm-charts/tree/main/charts/velero
+
+## node-problem-detector
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf node-problem-detector
+helm repo add deliveryhero https://charts.deliveryhero.io/
+helm repo update
+helm fetch --untar --untardir ./ deliveryhero/node-problem-detector
+```
+
+- Chart location: https://github.com/deliveryhero/helm-charts/blob/master/stable/node-problem-detector/Chart.yaml.

original_message:
Document updating node-problem-detector

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message: Add Rook update instructions

diff:
@@ -184,3 +184,27 @@ helm fetch --untar --untardir ./ deliveryhero/node-problem-detector
```
- Chart location: https://github.com/deliveryhero/helm-charts/blob/master/stable/node-problem-detector/Chart.yaml.
+
+## Rook
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf rook
+helm repo add rook-release https://charts.rook.io/release
+helm repo update
+helm fetch --untar --untardir ./ rook-release/rook-ceph
+mv rook-ceph rook
+git checkout rook/templates/service-monitor.yaml
+git checkout rook/templates/prometheus-ceph-v14-rules-for-prometheus-operator-0.43.2.yaml
+git checkout rook/templates/prometheus-ceph-v14-rules.yaml
+git checkout rook/templates/ceph-cluster.yaml
+git checkout rook/templates/ceph-osd.yaml
+git checkout rook/templates/ceph-pools.yaml
+git checkout rook/templates/csi-metrics-service-monitor.yaml
+git checkout rook/dashboards
+```
+
+- More information about the chart: https://rook.io/docs/rook/v1.5/helm-operator.html.
+- Code repository: https://github.com/rook/rook.

original_message:
Add Rook update instructions

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message: Add Linkerd update instructions

diff:
@@ -208,3 +208,19 @@ git checkout rook/dashboards
- More information about the chart: https://rook.io/docs/rook/v1.5/helm-operator.html.
- Code repository: https://github.com/rook/rook.
+
+## Linkerd
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf linkerd2
+helm repo add linkerd https://helm.linkerd.io/stable
+helm repo update
+helm fetch --untar --untardir ./ linkerd/linkerd2
+git checkout linkerd2/templates/service-monitors.yaml
+```
+
+- Code repository: https://github.com/linkerd/linkerd2.
+- Helm repo documentation: https://linkerd.io/2.10/tasks/install-helm/.

original_message:
Add Linkerd update instructions

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


diff:
@@ -224,3 +224,17 @@ git checkout linkerd2/templates/service-monitors.yaml
- Code repository: https://github.com/linkerd/linkerd2.
- Helm repo documentation: https://linkerd.io/2.10/tasks/install-helm/.
+
+## cluster-autoscaler
+
+Run the following commands in the root of this repository:
+
+```bash
+cd assets/charts/components
+rm -rf cluster-autoscaler
+helm repo add autoscaler https://kubernetes.github.io/autoscaler
+helm repo update
+helm fetch --untar --untardir ./ autoscaler/cluster-autoscaler
+```
+
+- Chart location: https://github.com/kubernetes/autoscaler/tree/master/charts/cluster-autoscaler

original_message:
Document how to update cluster-autoscaler

Signed-off-by: Maartje Eyskens <maartje@kinvolk.io>


message: Support dynamic imports in dev mode

diff:
@@ -56,6 +56,8 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
const export_from_identifiers = new Map();
let uid = 1;
+ const rewriteDynamicImportTo = '__dynamicImport';
+
ast.body.forEach(node => {
if (node.type === 'ImportDeclaration') {
imports.push(node);
@@ -117,22 +119,36 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
}
});
- if (/import\s*\.\s*meta/.test(data)) {
+ if (/import\s*\.\s*meta/.test(data) || /import *\(/.test(data)) {
walk(ast.body, {
enter(node: any) {
if (node.type === 'MetaProperty' && node.meta.name === 'import') {
code.overwrite(node.start, node.end, '__importmeta__');
}
+
+ // rename dynamic imports so we can inject a custom implementation
+ if (node.type === 'ImportExpression') {
+ code.overwrite(
+ (node as any).start,
+ (node as any).end,
+ `${rewriteDynamicImportTo}(${code.slice((node as any).source.start, (node as any).source.end)})`
+ );
+ }
}
});
}
+ function importDependency(dependency: string): Promise<any> {
+ return dependency[0] === '/' || dependency[0] === '.'
+ ? load(new URL(dependency, `http://localhost${url}`).pathname)
+ : Promise.resolve(load_node(dependency));
+ }
+
const deps = [];
imports.forEach(node => {
const source = node.source.value;
- const promise = source[0] === '/' || source[0] === '.'
- ? load(new URL(source, `http://localhost${url}`).pathname)
- : Promise.resolve(load_node(source));
+
+ const promise = importDependency(source)
if (node.type === 'ExportAllDeclaration' || node.type === 'ExportNamedDeclaration') {
// `export * from './other.js'` or `export { foo } from './other.js'`
@@ -169,10 +185,21 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
code.append(`\n//# sourceURL=${url}`);
- const fn = new Function('exports', '__importmeta__', ...deps.map(d => d.name).filter(Boolean), code.toString());
+ const fn = new Function(
+ 'exports',
+ '__importmeta__',
+ rewriteDynamicImportTo,
+ ...deps.map(d => d.name).filter(Boolean),
+ code.toString()
+ );
const values = await Promise.all(deps.map(d => d.promise));
- fn(cached.exports, { url }, ...values);
+ fn(
+ cached.exports,
+ { url },
+ importDependency,
+ ...values
+ );
return cached.exports;
}

license: MIT License

repo: sveltejs/kit

original_message: Support dynamic imports in dev mode


message: SetupModule with generics for Context and Session

diff:
@@ -23,10 +23,10 @@ export type PageResponse = EndpointResponse & {
dependencies?: Record<string, EndpointResponse>;
};
-type SetupModule = {
- prepare?: (headers: Headers) => Promise<{ context: any, headers: Headers }>;
- getSession?: (context: any) => Promise<any>;
- setSession?: (context: any, session: any) => Promise<any>;
+type SetupModule<Context = any, Session = any> = {
+ prepare?: (headers: Headers) => Promise<{ context: Context, headers: Headers }>;
+ getSession?: (context: Context) => Promise<Session>;
+ setSession?: (context: Context, session: Session) => Promise<Session>;
};
export type RenderOptions = {

diff:
@@ -132,6 +132,7 @@ class Watcher extends EventEmitter {
try {
setup = await load(`/_app/setup/index.js`);
+ setup = setup.default || setup
} catch (err) {
if (!err.message.endsWith('NOT_FOUND')) throw err;
setup = {};


message: build with ts without warnings

diff:
@@ -3,9 +3,9 @@ import { dirname, resolve as resolve_path } from 'path';
import { parse, resolve, URLSearchParams } from 'url';
import { mkdirp } from '../files';
import { render } from '../render';
-import { RouteManifest } from '../types';
+import { PageResponse, RouteManifest } from '../types';
-function clean_html(html) {
+function clean_html(html: string) {
return html
.replace(/<!\[CDATA\[[\s\S]*?\]\]>/gm, '')
.replace(/(<script[\s\S]*?>)[\s\S]*?<\/script>/gm, '$1</' + 'script>')
@@ -13,17 +13,17 @@ function clean_html(html) {
.replace(/<!--[\s\S]*?-->/gm, '');
}
-function get_href(attrs) {
+function get_href(attrs: string) {
const match = /href\s*=\s*(?:"(.*?)"|'(.*?)'|([^\s>]*))/.exec(attrs);
return match && (match[1] || match[2] || match[3]);
}
-function get_src(attrs) {
+function get_src(attrs: string) {
const match = /src\s*=\s*(?:"(.*?)"|'(.*?)'|([^\s>]*))/.exec(attrs);
return match && (match[1] || match[2] || match[3]);
}
-function get_srcset_urls(attrs) {
+function get_srcset_urls(attrs: string) {
const results = [];
// Note that the srcset allows any ASCII whitespace, including newlines.
const match = /srcset\s*=\s*(?:"(.*?)"|'(.*?)'|([^\s>]*))/s.exec(attrs);
@@ -130,9 +130,11 @@ export async function prerender({
log.error(`${rendered.status} ${path}`);
}
- if (rendered.dependencies) {
- for (const path in rendered.dependencies) {
- const result = rendered.dependencies[path];
+ const dependencies = (rendered as PageResponse).dependencies;
+
+ if (dependencies) {
+ for (const path in dependencies) {
+ const result = dependencies[path];
const response_type = Math.floor(result.status / 100);
const is_html = result.headers['content-type'] === 'text/html';

diff:
@@ -3,7 +3,7 @@ import render_page from './page';
import render_route from './route';
import { EndpointResponse, IncomingRequest, PageResponse, RenderOptions } from '../types';
-function md5(body) {
+function md5(body: string) {
return createHash('md5').update(body).digest('hex');
}

diff:
@@ -6,13 +6,13 @@ import devalue from 'devalue';
import fetch, { Response } from 'node-fetch';
import * as mime from 'mime';
import { render } from './index';
-import { IncomingRequest, RenderOptions, PageManifest } from '../types';
+import { IncomingRequest, RenderOptions, PageManifest, EndpointResponse, PageResponse, Headers } from '../types';
const noop = () => {};
type FetchOpts = {
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS';
- headers?: Record<string, string>;
+ headers?: Headers;
body?: any;
};
@@ -20,8 +20,13 @@ export default async function render_page(
request: IncomingRequest,
context: any,
options: RenderOptions
-) {
- let redirected;
+): Promise<{
+ status: number,
+ body?: string,
+ headers?: Headers,
+ dependencies?: Record< string, EndpointResponse | PageResponse>
+}> {
+ let redirected: { status: number; location?: string; headers: Headers };
let preload_error;
const page: PageManifest = options.manifest.pages.find(page => page.pattern.test(request.path));
@@ -53,10 +58,10 @@ export default async function render_page(
l++;
});
- const dependencies = {};
+ const dependencies: Record<string, EndpointResponse | PageResponse> = {};
const preload_context = {
- redirect: (status, location) => {
+ redirect: (status: number, location: string) => {
if (redirected && (redirected.status !== status || redirected.location !== location)) {
throw new Error(`Conflicting redirects`);
}

diff:
-import { IncomingRequest, RenderOptions, EndpointManifest } from '../types';
+import { IncomingRequest, RenderOptions, EndpointManifest, Headers } from '../types';
export default function render_route(
request: IncomingRequest,
context: any,
options: RenderOptions
-) {
+): Promise<{
+ status: number,
+ body: string,
+ headers?: Headers
+}> {
const route: EndpointManifest = options.manifest.endpoints.find(route => route.pattern.test(request.path));
if (!route) return;
@@ -53,7 +57,7 @@ export default function render_route(
});
}
-function lowercase_keys(obj) {
+function lowercase_keys(obj: Record<string, any>) {
const clone = {};
for (const key in obj) {
clone[key.toLowerCase()] = obj[key];

diff:
declare module "MANIFEST" {
export const components: any[];
export const routes: any[];
+ export const Layout: any;
}
declare module "ROOT" {

diff:
@@ -70,7 +70,9 @@ export function sourcemap_stacktrace(stack: string) {
return input;
}
- const consumer = new SourceMapConsumer(raw_sourcemap);
+ // TODO: according to typings, this code cannot work;
+ // the constructor returns a promise that needs to be awaited
+ const consumer = new (SourceMapConsumer as any)(raw_sourcemap);
const pos = consumer.originalPositionFor({
line: Number(line),
column: Number(column),

diff:
import relative from 'require-relative';
import sade from 'sade';
import colors from 'kleur';
-import * as pkg from '../package.json';
-import { ReadyEvent } from './interfaces';
+import pkg from '../package.json';
+import { ReadyEvent, SvelteAppConfig } from './interfaces';
-let config;
+let config: SvelteAppConfig;
try {
config = relative('./svelte.config.js', process.cwd());

diff:
{
"compilerOptions": {
- "declaration": true,
- "declarationDir": "declarations",
- "emitDeclarationOnly": true,
- "resolveJsonModule": true
+ "noEmit": true,
+ "resolveJsonModule": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "target": "ES6",
+ "outDir": "build",
+ "esModuleInterop": true
},
"lib": ["ES2020", "dom", "node"]
}

original_message: build with ts without warnings


message: Show good error message if project code has broken import

diff:
@@ -137,6 +137,23 @@ class Watcher extends EventEmitter {
setup = {};
}
+ let root;
+
+ try {
+ root = await load(`/_app/main/root.js`);
+
+ if (!root.default) {
+ res.statusCode = 500;
+ res.end('Failed to load root component');
+ return
+ }
+ }
+ catch (e) {
+ res.statusCode = 500;
+ res.end(e.toString());
+ return
+ }
+
const rendered = await render({
host: null, // TODO what should this be? is it necessary?
headers: req.headers,
@@ -153,7 +170,7 @@ class Watcher extends EventEmitter {
},
files: 'build',
dev: true,
- root: await load(`/_app/main/root.js`),
+ root,
setup,
load: route => load(route.url.replace(/\.\w+$/, '.js')) // TODO is the replace still necessary?
});


message: throw out failed loads from cache

diff:
@@ -141,12 +141,6 @@ class Watcher extends EventEmitter {
try {
root = await load(`/_app/main/root.js`);
-
- if (!root.default) {
- res.statusCode = 500;
- res.end('Failed to load root component');
- return
- }
}
catch (e) {
res.statusCode = 500;

diff:
@@ -6,10 +6,15 @@ import { Loader } from './types';
import { SnowpackDevServer } from 'snowpack';
import { walk } from 'estree-walker';
+interface CachedExports {
+ hash: number;
+ exports: any;
+}
+
// This function makes it possible to load modules from the 'server'
// snowpack server, for the sake of SSR
export default function loader(snowpack: SnowpackDevServer): Loader {
- const cache = new Map();
+ const cache = new Map<string, CachedExports>();
const get_module = (importer, imported) => imported[0] === '/' || imported[0] === '.'
? load(new URL(imported, `http://localhost${importer}`).pathname)
@@ -33,13 +38,24 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
let cached = cache.get(url);
const hash = get_hash(data);
- if (cached && cached.hash === hash) {
- return cached.exports;
- } else {
+ if (!cached || cached.hash !== hash) {
cached = { hash, exports: {} };
+
cache.set(url, cached);
+
+ try {
+ cached.exports = await initialize_module(url, data)
+ }
+ catch (e) {
+ cache.delete(url);
+ throw e
+ }
}
+ return cached.exports;
+ }
+
+ async function initialize_module(url: string, data: string) {
const code = new MagicString(data);
const ast = meriyah.parseModule(data, {
ranges: true,
@@ -169,8 +185,10 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
const fn = new Function('exports', 'global', 'require', '__import__', '__importmeta__', ...deps.map(d => d.name).filter(Boolean), code.toString());
const values = await Promise.all(deps.map(d => d.promise));
+ let exports = {};
+
fn(
- cached.exports,
+ exports,
global,
// require(...)
@@ -188,13 +206,13 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
...values
);
- return cached.exports;
+ return exports;
}
return load;
}
-function get_hash(str) {
+function get_hash(str: string) {
let hash = 5381;
let i = str.length;
@@ -202,7 +220,7 @@ function get_hash(str) {
return hash >>> 0;
}
-function load_node(source) {
+function load_node(source: string) {
// mirror Rollup's interop by allowing both of these:
// import fs from 'fs';
// import { readFileSync } from 'fs';

original_message: throw out failed loads from cache


message: server-side imports

diff:
<script>
+// import { goto } from '@sveltejs/kit/client';
+ import * as module from '@sveltejs/kit/client';
+
+// console.log('goto', goto)
+ console.log('module', module)
+
export let segment;
</script>

diff:
{
"compilerOptions": {
- "noEmit": true,
"resolveJsonModule": true,
"module": "esnext",
"moduleResolution": "node",
"target": "ES6",
"outDir": "build",
- "esModuleInterop": true
+ "esModuleInterop": true,
+ "noEmit": true,
+ "declarationDir": "declarations",
+ "declaration": true
},
"lib": ["ES2020", "dom", "node"]
}

diff:
@@ -25,6 +25,7 @@ module.exports = {
'src/setup': '/_app/setup'
},
alias: {
+ '@sveltejs/kit': '/_app/main',
$components: './src/components'
}
};
\ No newline at end of file

original_message: server-side imports


message: prevent multiple parallel loads from getting {}

diff:
@@ -8,7 +8,7 @@ import { walk } from 'estree-walker';
interface CachedExports {
hash: number;
- exports: any;
+ exports: Promise<any>;
}
// This function makes it possible to load modules from the 'server'
@@ -16,16 +16,22 @@ interface CachedExports {
export default function loader(snowpack: SnowpackDevServer): Loader {
const cache = new Map<string, CachedExports>();
- const get_module = (importer, imported) => imported[0] === '/' || imported[0] === '.'
- ? load(new URL(imported, `http://localhost${importer}`).pathname)
+ const get_module = (importer: string, imported: string, url_stack: string[]) =>
+ imported[0] === '/' || imported[0] === '.'
+ ? load(new URL(imported, `http://localhost${importer}`).pathname, url_stack)
: Promise.resolve(load_node(imported));
- async function load(url: string) {
+ async function load(url: string, url_stack: string[]) {
// TODO: meriyah (JS parser) doesn't support `import.meta.hot = ...` used in HMR setup code.
if (url.endsWith('.css.proxy.js')) {
return null;
}
+ if (url_stack.includes(url)) {
+ console.warn(`Circular dependency: ${url_stack.join(' -> ')} -> ${url}`);
+ return {}
+ }
+
let data: string;
try {
@@ -39,23 +45,22 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
const hash = get_hash(data);
if (!cached || cached.hash !== hash) {
- cached = { hash, exports: {} };
+ cached = {
+ hash,
+ exports: initialize_module(url, data, url_stack.concat(url))
+ .catch(e => {
+ cache.delete(url);
+ throw e;
+ })
+ };
cache.set(url, cached);
-
- try {
- cached.exports = await initialize_module(url, data)
- }
- catch (e) {
- cache.delete(url);
- throw e
- }
}
return cached.exports;
}
- async function initialize_module(url: string, data: string) {
+ async function initialize_module(url: string, data: string, url_stack: string[]) {
const code = new MagicString(data);
const ast = meriyah.parseModule(data, {
ranges: true,
@@ -145,7 +150,7 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
const deps = [];
imports.forEach(node => {
- const promise = get_module(url, node.source.value);
+ const promise = get_module(url, node.source.value, url_stack);
if (node.type === 'ExportAllDeclaration' || node.type === 'ExportNamedDeclaration') {
// `export * from './other.js'` or `export { foo } from './other.js'`
@@ -198,7 +203,7 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
},
// import(...)
- source => get_module(url, source),
+ source => get_module(url, source, url_stack),
// import.meta
{ url },
@@ -209,7 +214,7 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
return exports;
}
- return load;
+ return url => load(url, []);
}
function get_hash(str: string) {


message: build types on prepublish

diff:
/node_modules
/dist
/assets/client.*
+/types
+/client

diff:
},
"files": [
"assets",
- "dist"
+ "dist",
+ "client"
],
"scripts": {
"dev": "rollup -cw",
"build": "rollup -c",
"prepare": "npm run build",
- "prepublishOnly": "npm run build"
+ "prepublishOnly": "npm run build",
+ "prepublish": "tsc && cp -r types/src/client client"
}
}

diff:
@@ -2,6 +2,7 @@ declare module "MANIFEST" {
export const components: any[];
export const routes: any[];
export const Layout: any;
+ export const ErrorComponent: any;
}
declare module "ROOT" {

diff:
"target": "ES6",
"outDir": "build",
"esModuleInterop": true,
- "noEmit": true,
- "declarationDir": "declarations",
+ "emitDeclarationOnly": true,
+ "declarationDir": "types",
"declaration": true
},
+ "include": ["src/**/*", "types/src/**/*", "client"],
"lib": ["ES2020", "dom", "node"]
}

original_message: build types on prepublish


message: snowpack API calls for "utf8", not "utf-8"

diff:
@@ -35,7 +35,7 @@ export default function loader(snowpack: SnowpackDevServer): Loader {
let data: string;
try {
- const result = await snowpack.loadUrl(url, {isSSR: true, encoding: 'utf-8'});
+ const result = await snowpack.loadUrl(url, {isSSR: true, encoding: 'utf8'});
data = result.contents;
} catch (err) {
throw new Error(`Failed to load ${url}: ${err.message}`);


message: we have esinterop so old import style is fine

diff:
import relative from 'require-relative';
import sade from 'sade';
import colors from 'kleur';
-import pkg from '../package.json';
+import * as pkg from '../package.json';
import { ReadyEvent, SvelteAppConfig } from './interfaces';
let config: SvelteAppConfig;


message: rolled back unrelated change

diff:
@@ -132,7 +132,6 @@ class Watcher extends EventEmitter {
try {
setup = await load(`/_app/setup/index.js`);
- setup = setup.default || setup
} catch (err) {
if (!err.message.endsWith('NOT_FOUND')) throw err;
setup = {};

original_message: rolled back unrelated change


message: revert generics in types

diff:
@@ -23,10 +23,10 @@ export type PageResponse = EndpointResponse & {
dependencies?: Record<string, EndpointResponse>;
};
-type SetupModule<Context = any, Session = any> = {
- prepare?: (headers: Headers) => Promise<{ context: Context, headers: Headers }>;
- getSession?: (context: Context) => Promise<Session>;
- setSession?: (context: Context, session: Session) => Promise<Session>;
+type SetupModule = {
+ prepare?: (headers: Headers) => Promise<{ context: any, headers: Headers }>;
+ getSession?: (context: any) => Promise<any>;
+ setSession?: (context: any, session: any) => Promise<any>;
};
export type RenderOptions = {

original_message: revert generics in types


message: Eliminated the moving of typings

diff:
/node_modules
/dist
/assets/client.*
-/types
-/client
+/client/**/*.d.ts

diff:
+{
+ /* Generates the typings for client code */
+ "compilerOptions": {
+ "resolveJsonModule": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "target": "ES6",
+ "esModuleInterop": true,
+ "emitDeclarationOnly": true,
+ "declaration": true,
+ "outDir": "."
+ },
+ "include": ["../src/client/**/*", "../src/ambient.d.ts"],
+ "lib": ["ES2020", "dom", "node"]
+}

diff:
"build": "rollup -c",
"prepare": "npm run build",
"prepublishOnly": "npm run build",
- "prepublish": "tsc && cp -r types/src/client client"
+ "prepublish": "cd client; tsc"
}
}

diff:
@@ -6,5 +6,6 @@ declare module "MANIFEST" {
}
declare module "ROOT" {
- export default any;
+ const root: any;
+ export default root;
}

diff:
"module": "esnext",
"moduleResolution": "node",
"target": "ES6",
- "outDir": "build",
"esModuleInterop": true,
- "emitDeclarationOnly": true,
- "declarationDir": "types",
- "declaration": true
+ "noEmit": true
},
- "include": ["src/**/*", "client"],
+ "include": ["src/**/*"],
"lib": ["ES2020", "dom", "node"]
}

original_message: Eliminated the moving of typings


message: moved typing build to prepare

diff:
"scripts": {
"dev": "rollup -cw",
"build": "rollup -c",
- "prepare": "npm run build",
- "prepublishOnly": "npm run build",
- "prepublish": "cd client; tsc"
+ "prepare": "npm run build && cd client && tsc",
+ "prepublishOnly": "npm run build"
}
}

original_message: moved typing build to prepare


message: adding types to stores

diff:
import { getContext } from 'svelte';
+import { Readable, Writable } from 'svelte/store';
+import { Page } from '../navigation/types';
+
+// these Svelte types are not exported, so repeating them here.
+type Subscriber<T> = (value: T) => void;
+type Updater<T> = (value: T) => T;
+
+export type PageContext = Page & { error?: Error };
// const ssr = (import.meta as any).env.SSR;
const ssr = typeof window === 'undefined'; // TODO why doesn't previous line work in build?
export const getStores: () => {
- page: any // TODO
- preloading: any // TODO
- session: any // TODO
+ page: Readable<PageContext>
+ preloading: Readable<boolean>
+ session: Writable<any>
} = () => getContext('__svelte__');
export const page = {
- subscribe(fn) {
+ subscribe(fn: Subscriber<PageContext>) {
const store = getStores().page;
return store.subscribe(fn);
}
};
export const preloading = {
- subscribe(fn) {
+ subscribe(fn: Subscriber<boolean>) {
const store = getStores().preloading;
return store.subscribe(fn);
}
@@ -28,7 +36,7 @@ const error = verb => {
};
export const session = {
- subscribe(fn) {
+ subscribe(fn: Subscriber<any>) {
const store = getStores().session;
if (!ssr) {
@@ -38,6 +46,6 @@ export const session = {
return store.subscribe(fn);
},
- set: () => error('set'),
- update: () => error('update')
+ set: (updater: Updater<any>) => { error('set') },
+ update: (updater: Updater<any>) => { error('update') }
};
\ No newline at end of file

original_message: adding types to stores


message: moved pagecontext and introduced types to navigation/start/index.ts

diff:
@@ -6,10 +6,7 @@ import goto from '../goto';
import { page_store } from './page_store';
import { layout, ErrorComponent, components } from 'MANIFEST';
import root from 'ROOT';
-
-// TODO
-// import { PageContext } from '@sapper/common';
-type PageContext = any;
+import { PageContext } from '../types';
declare const __SVELTE__;
export const initial_data: InitialData = typeof __SVELTE__ !== 'undefined' && __SVELTE__;
@@ -22,8 +19,8 @@ let current_branch: Branch = [];
let current_query = '{}';
const stores = {
- page: page_store({}),
- preloading: writable(null),
+ page: page_store<PageContext>({} as any),
+ preloading: writable<boolean>(false),
session: writable(initial_data && initial_data.session)
};

diff:
@@ -43,3 +43,7 @@ export interface Page {
params: Record<string, string>;
query: Record<string, string | string[]>;
}
+
+export interface PageContext extends Page {
+ error?: Error
+};

diff:
import { getContext } from 'svelte';
import { Readable, Writable } from 'svelte/store';
-import { Page } from '../navigation/types';
+import { PageContext } from '../navigation/types';
// these Svelte types are not exported, so repeating them here.
type Subscriber<T> = (value: T) => void;
type Updater<T> = (value: T) => T;
-export type PageContext = Page & { error?: Error };
-
// const ssr = (import.meta as any).env.SSR;
const ssr = typeof window === 'undefined'; // TODO why doesn't previous line work in build?


message: fix merge in package.json

diff:
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "lint": "pnpm -r lint",
+ "lint": "pnpm -r lint"
},
"repository": {
"type": "git",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.5.0",
- "@typescript-eslint/eslint-plugin": "^4.5.0",
+ "@typescript-eslint/eslint-plugin": "^4.6.0",
+ "@typescript-eslint/parser": "^4.6.0",
"eslint": "^7.11.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-svelte3": "^2.7.3",
"rollup": "^2.32.0",
"tslib": "^2.0.3",
- "typescript": "^4.0.3",
- "@typescript-eslint/eslint-plugin": "^4.6.0",
- "@typescript-eslint/parser": "^4.6.0"
+ "typescript": "^4.0.3"
}
}

original_message: fix merge in package.json


message: update references to kit-mono repo

diff:
},
"repository": {
"type": "git",
- "url": "git+https://github.com/sveltejs/kit-mono.git"
+ "url": "git+https://github.com/sveltejs/kit.git"
},
"author": "",
"license": "MIT",
"bugs": {
- "url": "https://github.com/sveltejs/kit-mono/issues"
+ "url": "https://github.com/sveltejs/kit/issues"
},
- "homepage": "https://github.com/sveltejs/kit-mono#readme",
+ "homepage": "https://github.com/sveltejs/kit#readme",
"devDependencies": {
"@changesets/cli": "^2.11.1",
"@rollup/plugin-commonjs": "^15.1.0",

original_message: update references to kit-mono repo


message: Allowing app-utils to export types

diff: +export { EndpointManifest, PageManifest, PageComponentManifest } from './src/index';

change_type: RENAME

diff:
@@ -61,6 +61,7 @@ export type EndpointManifest = {
name: string;
pattern: RegExp;
file: string;
+ url: string;
params: string[];
};

diff:
-import { PageComponentManifest, RouteManifest, PageManifest, EndpointManifest } from '../../types';
+import { PageComponentManifest, RouteManifest, PageManifest, EndpointManifest } from '../../index';
const examplePageComponentManifest: PageComponentManifest = {
default: true,
@@ -20,6 +20,7 @@ const exampleEndpointManifest: EndpointManifest = {
name: 'grault',
pattern: /b/,
file: 'garply',
+ url: 'bla',
params: [ 'waldo', 'fred' ]
}

diff:
-import { RouteManifest, PageManifest, EndpointManifest } from '../../types';
+import { RouteManifest, PageManifest, EndpointManifest } from '../../index';
const array_item_delimiter = ',';

diff:
@@ -3,7 +3,7 @@ import { dirname, resolve as resolve_path } from 'path';
import { parse, resolve, URLSearchParams } from 'url';
import { mkdirp } from '../../files';
import { render } from '../render';
-import { PageResponse, RouteManifest } from '../../types';
+import { PageResponse, RouteManifest } from '../../index';
function clean_html(html: string) {
return html

diff:
-import { IncomingRequest, RenderOptions, EndpointManifest, Headers } from '../../types';
+import { IncomingRequest, RenderOptions, EndpointManifest, Headers } from '../../index';
export default function render_route(
request: IncomingRequest,

diff:
import { createHash } from 'crypto';
import render_page from './page';
import render_endpoint from './endpoint';
-import { EndpointResponse, IncomingRequest, PageResponse, RenderOptions } from '../../types';
+import { EndpointResponse, IncomingRequest, PageResponse, RenderOptions } from '../../index';
function md5(body: string) {
return createHash('md5').update(body).digest('hex');

diff:
@@ -6,7 +6,7 @@ import devalue from 'devalue';
import fetch, { Response } from 'node-fetch';
import * as mime from 'mime';
import { render } from './index';
-import { IncomingRequest, RenderOptions, PageManifest, EndpointResponse, PageResponse, Headers } from '../../types';
+import { IncomingRequest, RenderOptions, PageManifest, EndpointResponse, PageResponse, Headers } from '../../index';
const noop = () => {};

diff:
@@ -13,6 +13,7 @@ import { copy_assets } from '../utils';
import { create_app } from '../../core/create_app';
import { SvelteAppConfig } from '../../interfaces';
import { css_injection } from './css_injection';
+import { EndpointManifest } from '@sveltejs/app-utils';
const exec = promisify(child_process.exec);
@@ -88,7 +89,7 @@ export async function build(config: SvelteAppConfig) {
...manifest.components,
...manifest.endpoints
].forEach(item => {
- server_input[`routes/${item.name}`] = `${unoptimized}/server${item.url.replace(
+ server_input[`routes/${item.name}`] = `${unoptimized}/server${(item as EndpointManifest).url.replace(
/\.\w+$/,
'.js'
)}`;

diff:
+import { PageComponentManifest, PageManifest, EndpointManifest } from '@sveltejs/app-utils';
+
export type SvelteAppConfig = {
adapter: string;
}
@@ -26,29 +28,6 @@ export type WritableStore<T> = {
subscribe: (fn: (T: any) => void) => () => void;
};
-export type PageComponentManifest = {
- file: string;
- name: string;
- url: string;
-};
-
-export type PageManifest = {
- path: string;
- pattern: RegExp;
- parts: Array<{
- component: PageComponentManifest;
- params: string[];
- }>;
-};
-
-export type EndpointManifest = {
- name: string;
- pattern: RegExp;
- file: string;
- url: string;
- params: string[];
-};
-
export type Dirs = {
dest: string;
src: string;

original_message: Allowing app-utils to export types


message: Renamed index.d.ts to types

diff:
-export { EndpointManifest, PageManifest, PageComponentManifest } from './src/index';
+export { EndpointManifest, PageManifest, PageComponentManifest } from './src/types';

diff:
-import { PageComponentManifest, RouteManifest, PageManifest, EndpointManifest } from '../../index';
+import { PageComponentManifest, RouteManifest, PageManifest, EndpointManifest } from '../../types';
const examplePageComponentManifest: PageComponentManifest = {
default: true,

diff:
-import { RouteManifest, PageManifest, EndpointManifest } from '../../index';
+import { RouteManifest, PageManifest, EndpointManifest } from '../../types';
const array_item_delimiter = ',';

diff:
@@ -3,7 +3,7 @@ import { dirname, resolve as resolve_path } from 'path';
import { parse, resolve, URLSearchParams } from 'url';
import { mkdirp } from '../../files';
import { render } from '../render';
-import { PageResponse, RouteManifest } from '../../index';
+import { PageResponse, RouteManifest } from '../../types';
function clean_html(html: string) {
return html

diff:
-import { IncomingRequest, RenderOptions, EndpointManifest, Headers } from '../../index';
+import { IncomingRequest, RenderOptions, EndpointManifest, Headers } from '../../types';
export default function render_route(
request: IncomingRequest,

diff:
import { createHash } from 'crypto';
import render_page from './page';
import render_endpoint from './endpoint';
-import { EndpointResponse, IncomingRequest, PageResponse, RenderOptions } from '../../index';
+import { EndpointResponse, IncomingRequest, PageResponse, RenderOptions } from '../../types';
function md5(body: string) {
return createHash('md5').update(body).digest('hex');

diff:
@@ -6,7 +6,7 @@ import devalue from 'devalue';
import fetch, { Response } from 'node-fetch';
import * as mime from 'mime';
import { render } from './index';
-import { IncomingRequest, RenderOptions, PageManifest, EndpointResponse, PageResponse, Headers } from '../../index';
+import { IncomingRequest, RenderOptions, PageManifest, EndpointResponse, PageResponse, Headers } from '../../types';
const noop = () => {};

diff:
@@ -44,6 +44,7 @@ export type RenderOptions = {
export type PageComponentManifest = {
default?: boolean;
type?: string;
+ url: string;
name: string;
file: string;
};

diff:
import * as fs from 'fs';
import { mkdirp } from '@sveltejs/app-utils/files';
import { stringify, walk, write_if_changed } from '../utils';
-import { PageManifest, ManifestData } from '../interfaces';
+import { ManifestData } from '../interfaces';
+import { PageManifest } from '@sveltejs/app-utils';
export function create_app({
manifest_data,

diff:
import * as fs from 'fs';
import * as path from 'path';
-import { PageManifest, PageComponentManifest, EndpointManifest, ManifestData } from '../interfaces';
+import { ManifestData } from '../interfaces';
+import { PageManifest, PageComponentManifest, EndpointManifest } from '@sveltejs/app-utils';
import { posixify, reserved_words } from '../utils';
export default function create_manifest_data(cwd: string, extensions: string = '.svelte .html'): ManifestData {

original_message: Renamed index.d.ts to types


message: removed unnecessary cast

diff:
@@ -89,7 +89,7 @@ export async function build(config: SvelteAppConfig) {
...manifest.components,
...manifest.endpoints
].forEach(item => {
- server_input[`routes/${item.name}`] = `${unoptimized}/server${(item as EndpointManifest).url.replace(
+ server_input[`routes/${item.name}`] = `${unoptimized}/server${item.url.replace(
/\.\w+$/,
'.js'
)}`;

original_message: removed unnecessary cast


message: Types for RenderOptions.root

diff:
-export { EndpointManifest, PageManifest, PageComponentManifest } from './src/types';
+export {
+ EndpointManifest,
+ PageManifest,
+ PageComponentManifest,
+ SetupModule,
+ RootModule
+} from './src/types';

diff:
@@ -4,8 +4,9 @@ const examplePageComponentManifest: PageComponentManifest = {
default: true,
type: 'foo',
name: 'bar',
- file: 'baz'
-}
+ file: 'baz',
+ url: 'boo'
+};
const examplePageManifest: PageManifest = {
pattern: /a/,
@@ -14,7 +15,7 @@ const examplePageManifest: PageManifest = {
component: examplePageComponentManifest,
params: [ 'quux', 'corge' ]
} ]
-}
+};
const exampleEndpointManifest: EndpointManifest = {
name: 'grault',
@@ -22,7 +23,7 @@ const exampleEndpointManifest: EndpointManifest = {
file: 'garply',
url: 'bla',
params: [ 'waldo', 'fred' ]
-}
+};
export const exampleRouteManifest: RouteManifest = {
layout: examplePageComponentManifest,
@@ -30,4 +31,4 @@ export const exampleRouteManifest: RouteManifest = {
components: [ examplePageComponentManifest, examplePageComponentManifest ],
pages: [ examplePageManifest, examplePageManifest ],
endpoints: [ exampleEndpointManifest, exampleEndpointManifest ]
-}
+};

diff:
@@ -23,19 +23,31 @@ export type PageResponse = EndpointResponse & {
dependencies: Record<string, EndpointResponse>;
};
-type SetupModule = {
+export type SetupModule = {
prepare?: (headers: Headers) => Promise<{ context: any, headers: Headers }>;
getSession?: (context: any) => Promise<any>;
setSession?: (context: any, session: any) => Promise<any>;
};
+export interface SSRComponentModule {
+ default: SSRComponent;
+}
+
+export interface SSRComponent {
+ render(props: unknown): {
+ html: string
+ head: string
+ css: { code: string, map: unknown };
+ }
+}
+
export type RenderOptions = {
only_prerender: boolean; // TODO this shouldn't really be part of the public API
static_dir: string;
template: string;
manifest: RouteManifest;
client: ClientManifest;
- root: any; // TODO
+ root: SSRComponentModule;
setup: SetupModule;
load: (route: PageComponentManifest | EndpointManifest) => Promise<any>; // TODO
dev: boolean; // TODO this is awkward

diff:
@@ -14,6 +14,7 @@ import { ManifestData, ReadyEvent } from '../../interfaces';
import { mkdirp } from '@sveltejs/app-utils/files';
import { render } from '@sveltejs/app-utils/renderer';
import { get_body } from '@sveltejs/app-utils/http';
+import { RootModule, SetupModule } from '@sveltejs/app-utils';
import { DevConfig, Loader } from './types';
import { copy_assets } from '../utils';
import { readFileSync } from 'fs';
@@ -129,24 +130,24 @@ class Watcher extends EventEmitter {
);
const parsed = parse(req.url);
- let setup;
+ let setup: SetupModule;
try {
- setup = await load(`/_app/setup/index.js`);
+ setup = await load('/_app/setup/index.js');
} catch (err) {
if (!err.message.endsWith('NOT_FOUND')) throw err;
setup = {};
}
- let root;
+ let root: RootModule;
try {
- root = await load(`/_app/main/generated/root.js`);
+ root = await load('/_app/main/generated/root.js');
}
catch (e) {
res.statusCode = 500;
res.end(e.toString());
- return
+ return;
}
const body = await get_body(req);

original_message: Types for RenderOptions.root


message: wrong name for root module

diff:
@@ -3,5 +3,5 @@ export {
PageManifest,
PageComponentManifest,
SetupModule,
- RootModule
+ SSRComponentModule
} from './src/types';

diff:
@@ -14,7 +14,7 @@ import { ManifestData, ReadyEvent } from '../../interfaces';
import { mkdirp } from '@sveltejs/app-utils/files';
import { render } from '@sveltejs/app-utils/renderer';
import { get_body } from '@sveltejs/app-utils/http';
-import { RootModule, SetupModule } from '@sveltejs/app-utils';
+import { SSRComponentModule, SetupModule } from '@sveltejs/app-utils';
import { DevConfig, Loader } from './types';
import { copy_assets } from '../utils';
import { readFileSync } from 'fs';
@@ -139,7 +139,7 @@ class Watcher extends EventEmitter {
setup = {};
}
- let root: RootModule;
+ let root: SSRComponentModule;
try {
root = await load('/_app/main/generated/root.js');

original_message: wrong name for root module


message: Made error page work

diff:
@@ -19,7 +19,9 @@ type FetchOpts = {
export default async function render_page(
request: IncomingRequest,
context: any,
- options: RenderOptions
+ options: RenderOptions,
+ status: number = 200,
+ error?: Error
): Promise<{
status: number,
body: string,
@@ -192,14 +194,15 @@ export default async function render_page(
});
const props: Record<string, any> = {
- status: 200,
- error: null,
+ status,
+ error,
stores: {
page: readable({
host: request.host,
path: request.path,
query: request.query,
- params
+ params,
+ error
}, noop),
preloading: readable(null, noop),
session: writable(session)
@@ -266,8 +269,8 @@ export default async function render_page(
<script>
__SVELTE__ = {
baseUrl: "${baseUrl}",
- status: 200,
- error: null,
+ status: ${status},
+ error: ${serialize_error(error)},
preloaded: ${serialized_preloads},
session: ${serialized_session}
};
@@ -283,52 +286,19 @@ export default async function render_page(
body: html,
dependencies
};
- } catch (error) {
- console.error(error.stack);
-
- const status = error.status || 500;
-
- try {
- const rendered = options.root.default.render({ status, error });
-
- const head = `${rendered.head}
- <script type="module">
- import { start } from '/_app/${options.client.entry}';
-
- start({
- target: document.body
- });
- </script>`.replace(/^\t\t\t/gm, '');
-
- const body = `${rendered.html}
- <script>
- __SVELTE__ = {
- baseUrl: "${baseUrl}",
- status: ${status},
- error: ${serialize_error(error)},
- preloaded: null,
- session: ${serialized_session}
- };
- </script>`.replace(/^\t\t\t/gm, '');
-
- const html = options.template
- .replace('%svelte.head%', head)
- .replace('%svelte.body%', body);
+ } catch (thrown) {
+ console.error(thrown.stack);
- return {
- status,
- headers: {
- 'content-type': 'text/html'
- },
- body: html,
- dependencies: {}
- };
- } catch (error) {
+ if (!error) {
+ const status = thrown.status || 500;
+ return render_page(request, context, options, status, thrown);
+ }
+ else {
// oh lawd now you've done it
return {
status: 500,
headers: {},
- body: error.stack, // TODO probably not in prod?
+ body: thrown.stack, // TODO probably not in prod?
dependencies: {}
};
}
@@ -345,7 +315,7 @@ function try_serialize(data: any, fail?: (err: Error) => void) {
}
// Ensure we return something truthy so the client will not re-render the page over the error
-function serialize_error(error: Error) {
+function serialize_error(error?: Error) {
if (!error) return null;
let serialized = try_serialize(error);
if (!serialized) {

original_message: Made error page work


message: default error to null (not undefined) to be consistent on client and server

diff:
@@ -21,7 +21,7 @@ export default async function render_page(
context: any,
options: RenderOptions,
status: number = 200,
- error?: Error
+ error: Error | null = null
): Promise<{
status: number,
body: string,


message: else and braces

diff:
@@ -292,8 +292,7 @@ export default async function render_page(
if (!error) {
const status = thrown.status || 500;
return render_page(request, context, options, status, thrown);
- }
- else {
+ } else {
// oh lawd now you've done it
return {
status: 500,

original_message: else and braces


message: allow sync methods in SetupModule

diff:
@@ -23,12 +23,6 @@ export interface PageResponse extends EndpointResponse {
dependencies: Record<string, EndpointResponse>;
}
-export interface SetupModule {
- prepare?: (headers: Headers) => Promise<{ context: any, headers: Headers }>;
- getSession?: (context: any) => Promise<any>;
- setSession?: (context: any, session: any) => Promise<any>;
-}
-
export interface SSRComponentModule {
default: SSRComponent;
}
@@ -41,6 +35,12 @@ export interface SSRComponent {
}
}
+export interface SetupModule<Context = any, Session = any> {
+ prepare?: (headers: Headers) => Promise<{ context: Context, headers: Headers }>;
+ getSession?: (context: Context) => Promise<Session> | Session;
+ setSession?: (context: Context, session: Session) => Promise<Session> | Session;
+}
+
export interface RenderOptions {
only_prerender: boolean; // TODO this shouldn't really be part of the public API
static_dir: string;

original_message: allow sync methods in SetupModule


message: moved setupmodule back to original place

diff:
@@ -23,6 +23,12 @@ export interface PageResponse extends EndpointResponse {
dependencies: Record<string, EndpointResponse>;
}
+export interface SetupModule<Context = any, Session = any> {
+ prepare?: (headers: Headers) => Promise<{ context: Context, headers: Headers }>;
+ getSession?: (context: Context) => Promise<Session> | Session;
+ setSession?: (context: Context, session: Session) => Promise<Session> | Session;
+}
+
export interface SSRComponentModule {
default: SSRComponent;
}
@@ -35,12 +41,6 @@ export interface SSRComponent {
}
}
-export interface SetupModule<Context = any, Session = any> {
- prepare?: (headers: Headers) => Promise<{ context: Context, headers: Headers }>;
- getSession?: (context: Context) => Promise<Session> | Session;
- setSession?: (context: Context, session: Session) => Promise<Session> | Session;
-}
-
export interface RenderOptions {
only_prerender: boolean; // TODO this shouldn't really be part of the public API
static_dir: string;


diff:
"tiny-glob": "^0.2.6"
},
"devDependencies": {
- "@sveltejs/app-utils": "*"
+ "@sveltejs/app-utils": "workspace:*"
}
}

diff:
@@ -125,7 +125,7 @@ importers:
devDependencies:
'@sveltejs/app-utils': 'link:../app-utils'
specifiers:
- '@sveltejs/app-utils': '*'
+ '@sveltejs/app-utils': 'workspace:*'
tiny-glob: ^0.2.6
packages/app-utils:
dependencies:

original_message: Wrong version of app-util in adapter-vercel (#131)


diff: +/// <reference types="@sveltejs/kit" />

diff:
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "$components/*": ["./src/components/*"]
+ }
+ }
+}

diff:
@@ -58,7 +58,11 @@ function add_tsconfig(cwd: string): void {
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
- "forceConsistentCasingInFileNames": true
+ "forceConsistentCasingInFileNames": true,
+ "baseUrl": ".",
+ "paths": {
+ "$components/*": ["./src/components/*"]
+ }
},
"include": ["src/**/*"],
"exclude": ["node_modules/*", ".svelte"]
@@ -69,7 +73,9 @@ function add_tsconfig(cwd: string): void {
function add_d_ts_file(cwd: string): void {
fs.writeFileSync(
path.join(cwd, 'src', 'globals.d.ts'),
- `//#region Ensure Svelte file endings have a type for TypeScript
+ `/// <reference types="@sveltejs/kit" />
+
+//#region Ensure Svelte file endings have a type for TypeScript
/**
* These declarations tell TypeScript that we allow import of Svelte files in TS files, e.g.
* \`\`\`

diff:
/dist
/assets/runtime
/client/**/*.d.ts
+index.d.ts

change_type: DELETE

diff:
-{
- /* Generates the typings for client code */
- "compilerOptions": {
- "resolveJsonModule": true,
- "module": "esnext",
- "moduleResolution": "node",
- "target": "ES6",
- "esModuleInterop": true,
- "declaration": true,
- "outDir": "."
- },
- "include": ["../src/client/**/*", "../src/ambient.d.ts"],
- "lib": ["ES2020", "dom", "node"]
-}

diff:
"files": [
"assets",
"dist",
- "client"
+ "index.d.ts"
],
"scripts": {
"dev": "rollup -cw",
"build": "rollup -c",
- "lint": "eslint --ignore-pattern node_modules/ --ignore-pattern dist/ '**/*.{ts,js,svelte}'",
+ "lint": "eslint --ignore-pattern node_modules/ --ignore-pattern dist/ '**/*.{ts,mjs,js,svelte}'",
"format": "prettier --write . --config ../../.prettierrc --ignore-path ../../.prettierignore",
- "prepare": "npm run build && cd client && tsc",
+ "prepare": "npm run build",
"prepublishOnly": "npm run build"
}
}

diff:
@@ -3,6 +3,7 @@ import json from '@rollup/plugin-json';
import resolve from '@rollup/plugin-node-resolve';
import typescript from 'rollup-plugin-typescript2';
import pkg from './package.json';
+import { readFileSync, writeFileSync } from 'fs';
const external = [].concat(
Object.keys(pkg.dependencies || {}),
@@ -35,7 +36,23 @@ export default [
resolve({
extensions: ['.mjs', '.js', '.ts']
}),
- typescript()
+ typescript({
+ tsconfigDefaults: {
+ compilerOptions: {
+ // create typings. these options do not apply to the other build target
+ declaration: true,
+ emitDeclarationOnly: true,
+ outFile: "./index.js"
+ }
+ },
+ useTsconfigDeclarationDir: true
+ }),
+ {
+ name: 'adjust-typings',
+ resolveId: () => null,
+ load: () => null,
+ writeBundle: adjust_typings
+ }
]
},
@@ -64,3 +81,25 @@ export default [
preserveEntrySignatures: false
}
];
+
+/**
+ * Remove the typings that do not refer to the runtime and fix the module names
+ * (e.g. change "src/runtime/navigation/goto/index" to "$app/navigation/goto")
+ */
+function adjust_typings() {
+ const alias = '$app';
+
+ const typings_file = 'index.d.ts';
+
+ const only_runtime = code =>
+ Array.from(code.matchAll(/declare module "src\/runtime\/.*?\n}/gms))
+ .map(m => m[0])
+ .join('\n\n');
+
+ const code = only_runtime(readFileSync(typings_file, 'utf8')).replace(
+ / (module|from) ['"]src\/runtime\/(.+?)(\/index)?['"]/g,
+ ` $1 "${alias}/$2"`
+ );
+
+ writeFileSync(typings_file, code);
+}

diff:
"moduleResolution": "node",
"target": "ES6",
"esModuleInterop": true,
- "noEmit": true,
+ "skipLibCheck": true,
"noEmitOnError": true
},
"include": ["src/**/*"],

original_message: Typings generation that works with $app path (#92)