Labring Laf Versions Save

Laf is a cloud development platform offering ready-to-use resources like cloud functions, databases, and storage. It empowers developers to quickly unleash their creativity.

v1.0.0-beta.14

5 months ago

Security Upgrades

CVE Fixed: https://nvd.nist.gov/vuln/detail/CVE-2023-48225

@see https://github.com/labring/laf/security/advisories/GHSA-hv2g-gxx4-fwxp

⚠️ All private deployments should update to the latest version of laf to fix this CVE.

Updates

Simple cloud storage API

import cloud from '@lafjs/cloud'

export default async function (ctx: FunctionContext) {

  // get bucket
  const bucket = cloud.storage.bucket('cloud-bin')

  // create file
  await bucket.writeFile('test.html', 'hello, laf', { ContentType: 'text/html' })

  // read file
  const res = await bucket.readFile('test.html')
  console.log(await res.Body.transformToString())

  // list files
  const result = await bucket.listFiles()
  console.log(result.Contents)

  // delete file
  await bucket.deleteFile('test.html')

  return { data: 'hi, laf' }
}

Support npm packages caching

The newly added support for node modules caching includes:

  • The npm dependencies added by the application are automatically packaged and cached in the cloud-bin bucket. (node_modules.tar)
  • This effectively improves the speed of application startup.
  • A cloud-bin bucket is automatically created when the application starts.

Support offline dependencies installation mode (runtime)

To support offline dependencies installation mode:

  • Add LF_NODE_MODULES_CACHE=always environment variable to your application
  • Upload your node_modules.tar to {appid}-cloud-bin bucket manually

Then the runtime would skip npm install command, and use node_modules.tar instead.

Seperate the custom npm packages from built-in's

You can add npm packages which has different version with built-in packages in runtime.

Logging & monitor optimization and some bug fixes

  • Upgrade node 18 to node 20 of runtime
  • Fix ObjectId problem in laf web database management

check the change logs.

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.13...v1.0.0-beta.14

Migration Guides

Update laf-server & laf-web images:

# upgrade laf SERVER
kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.14

# upgrade laf WEB
kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.14

Update sys_db.Runtime to upgrade runtime images in MongoDb

use sys_db
// runtime version
const version = "1.0.0-beta.14"

const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()

v1.0.0-beta.13

6 months ago

Intro

Performance Enhanced

In this version, we have restructured the cloud function runtime, enhancing the execution performance of cloud functions by over 400%, HTTP request QPS by more than 300% (with CPU usage savings of over 200% under the same concurrency), and Websocket long connection performance by over 500%.

New logger implementent of runtime

Additionally, we have restructured the function log implementation, now directly using Runtime Pod log streams, which supports real-time log viewing and beautification of log formats.

New billing & monitoring implement of application

We have also rewritten application resource monitoring and metered billing, enabling laf in the sealos user namespace to support resource monitoring and metered billing functions.

What's Changed

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.12...v1.0.0-beta.13

Migration Guides

Update laf-server & laf-web images:

# upgrade laf SERVER
kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.13

# upgrade laf WEB
kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.13

Update sys_db.Runtime to upgrade runtime images in MongoDb

use sys_db
// runtime version
const version = "1.0.0-beta.13"

const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()

Restart all Running applications by update sys_db.Application in MongoDb

use sys_db
db.Application.updateMany({ state: 'Running' }, {
    $set: {
        state: 'Restarting'
    }
})

Enabling Resource Monitoring

This version of Laf uses a specialized runtime exporter for runtime resource metrics collection, so you will need to install the runtime exporter into the cluster to enable resource monitoring

kubectl apply  --namespace=laf-system  -f  - <<EOF
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
  name: runtime-exporter
spec:
  ports:
    - name: http
      port: 2342
      protocol: TCP
      targetPort: http
  selector:
    app.kubernetes.io/name: runtime-exporter
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
  name: runtime-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: runtime-exporter
  template:
    metadata:
      labels:
        app.kubernetes.io/name: runtime-exporter
    spec:
      automountServiceAccountToken: true
      serviceAccountName: laf-server # It's the same as the laf server's sa.
      securityContext: {}
      containers:
        - image: docker.io/lafyun/runtime-exporter:latest
          imagePullPolicy: Always
          name: runtime-exporter
          ports:
            - name: http
              containerPort: 2342
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /healthz
              port: http
          readinessProbe:
            httpGet:
              path: /healthz
              port: http
          env:
            - name: API_SECRET
              value: "fafafafa"
            - name: NAMESPACE
              value: "laf-system" # Depends on the namespace of the runtime.
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
    release: prometheus
  name: runtime-exporter
spec:
  endpoints:
    - interval: 60s
      path: "/runtime/metrics/fafafafa"    # fafafafa is consistent with the runtime exporter's environment variable API_SECRET
      scrapeTimeout: 10s
      honorLabels: true
  namespaceSelector:
    matchNames:
      - laf-system # Depends on the namespace of the runtime exporter.
  selector:
    matchLabels:
      app.kubernetes.io/name: runtime-exporter
---
# Application billing rules
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
    release: prometheus
  name: prometheus-laf-billing.rules
spec:
  groups:
    - name: prometheus-laf-billing.rules
      interval: 60s
      rules:
        - record: laf:billing:cpu
          expr: max_over_time(sum by (appid) (laf_runtime_cpu_limit{container!=""})[1h:])
        - record: laf:billing:memory
          expr: max_over_time(sum by (appid) (laf_runtime_memory_limit{container!=""})[1h:])
EOF

v1.0.0-beta.12

6 months ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.11...v1.0.0-beta.12

Migration Guides

Update laf-server & laf-web images:

# upgrade laf SERVER
kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.12

# upgrade laf WEB
kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.12

Update sys_db to upgrade runtime images

// runtime version
const version = "1.0.0-beta.12"
// const version = "1.0.0-beta.12"

const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
		version: version,
    image: {
      main: main_image,
      init: init_image
    }
	}
})

db.Runtime.find().pretty()

Update sys_db.Region if you still use apisix gateway:

Deprecated: apisix gateway is deprecated in laf, will not be supported in future.

use sys_db
db.Region.updateOne({}, {
    $set: {
        namespaceConf: {
            mode: 'appid',
            prefix: '',
            fixed: ''
        },
        'gatewayConf.tls.wildcardCertificateSecretName': null,
        'gatewayConf.driver': 'apisix'
    }
})

Migrate apisix gateway to nginx ingress gateway:

First stop all laf applications by update sys_db:

use sys_db;
db.Application.updateMany({ state: 'Running' }, {
    $set: {
        state: 'Stopped',
        _restart_flag: 'migration-gateway'
    }
})

Waiting for all application stopped.

# stop laf-server
kubectl scale deployment laf-server -n laf-system --replicas=0

# uninstall apisix
helm delete apisix --namespace laf-system

sealos run docker.io/labring/ingress-nginx:v1.8.1 \
      -e HELM_OPTS="-n ingress-nginx --set controller.hostNetwork=true --set controller.kind=DaemonSet --set controller.service.enabled=false"

kubectl create namespace laf-runtime
use sys_db
db.Region.updateOne({}, {
    $set: {
        namespaceConf: {
            mode: 'fixed',
            prefix: '',
            fixed: 'laf-runtime'
        },
        'gatewayConf.tls.wildcardCertificateSecretName': '',
        'gatewayConf.driver': 'nginx'
    }
})
# start laf-server
kubectl scale deployment laf-server -n laf-system --replicas=1

Start all applications:

db.Application.updateMany({ state: 'Stopped', _restart_flag: 'migration-gateway' }, {
        $set: { state: 'Running' }
    })

v1.0.0-beta.11

8 months ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.10...v1.0.0-beta.11

v1.0.0-beta.10

10 months ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.9...v1.0.0-beta.10

Migration Guides

Update sys_db to support autoscaling of applications:

db.ApplicationBundle.updateMany({}, {
    $set: { 
        autoscaling: {
            enable: false,
            minReplicas: 1,
            maxReplicas: 5,
            targetCPUUtilizationPercentage: null,
            targetMemoryUtilizationPercentage: null,
        },
    }
})

Update sys_db to support invitation bonus:

db.Setting.insertOne({
  public: true,
  key: 'invitation_profit',
  value: 500,
  desc: "Set up invitation rebate"
})

Update laf-server & laf-web images:

# upgrade laf SERVER
kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.10

# upgrade laf WEB
kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.10

Update sys_db to upgrade runtime images

// runtime version
const version = "1.0.0-beta.10"
// const version = "1.0.0-beta.10"

const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
		version: version,
    image: {
      main: main_image,
      init: init_image
    }
	}
})

db.Runtime.find().pretty()

v1.0.0-beta.9

11 months ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.8...v1.0.0-beta.9

Key Points

  • laf has implemented a new measuring and billing mechanism. https://github.com/labring/laf/pull/1187
  • remove prisma in laf server
  • support history mode route in websitehosting
  • support multiple-level url for cloud function
  • add laf ai polit

Migration Guides

Upgrade the server and web image version:

run this in your master node to upgrade laf-server & laf-web

kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.9

kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.9

To support new billing mechanism, you should add a new field to Application collection in system database.

run this in your mongodb shell.

use sys_db;
db.Application.updateMany({}, {
    $set: { 
        billingLockedAt: new Date('1970-01-01T00:00:00.000Z')
    }
})

To support multi-level url path in cloud function:

run this in your mongodb shell to upgrade runtime version

 use sys_db;

// runtime version
const version = "1.0.0-beta.9"
const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node-init:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()

Add new environment to laf-server deployments:

kubectl edit deployment/laf-server -n laf-system
env:
    - name: METERING_DATABASE_URL
     value: >-
         mongodb://your-root-user:your-password@mongo-cluster-rs0-0.mongo-cluster-rs0.default.svc.cluster.local:27017/sealos-resources?authSource=admin&replicaSet=rs0&w=majority

v1.0.0-beta.8

1 year ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.7...v1.0.0-beta.8

v1.0.0-beta.7

1 year ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.6...v1.0.0-beta.7

Upgrade Guide

run this in your master node to upgrade laf-server & laf-web

kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.7

kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.7

run this in your mongodb shell to upgrade runtime version

use sys_db;

// runtime version
const version = "1.0.0-beta.7"
const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node-init:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()
``

v1.0.0-beta.6

1 year ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.5...v1.0.0-beta.6

Upgrade Guide

kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.6

kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.6

! Urgent Security Upgrade

It is crucial to update your Minio version to RELEASE.2023-03-22T06-36-24Z in order to address the critical vulnerability CVE-2023-28432

New Configurations

To support auto-ssl-cert for website hosting, run this in your master node

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: laf-issuer
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: apisix
EOF

v1.0.0-beta.5

1 year ago

What's Changed

New Contributors

Full Changelog: https://github.com/labring/laf/compare/v1.0.0-beta.4...v1.0.0-beta.5

Migration points

Update Key Points

  • Add and adjust bundle fields
  • Subscription module
  • Account module
  • WeChat payment service
  • Improve multiple-region support

Breaks Changes

  1. Database: Bundle schema changes

    1. add limitCountPerUser field
    2. remove resource.limitCountPerUser field
    3. add subscriptionOptions field
    4. add resource.reservedTimeAfterExpired field
    5. add maxRenewalTime field
    6. remove specialPrice and price field
    • Operations

      db.Bundle.updateMany({}, {
      	$set: {
      		limitCountPerUser: 1,
      		maxRenewalTime: 3888000,
      		subscriptionOptions: [
      	    {
      	      "name": "monthly",
      	      "displayName": "1 Month",
      	      "duration": 2678400,
      	      "price": 0,
      	      "specialPrice": 0
      	    }
      		],
      		"resource.reservedTimeAfterExpired": 2678400
        }
      })
      
  2. Database: ApplicationBundle schema changes

    1. remove resource.limitCountPerUser field
    2. add resource.reservedTimeAfterExpired field
    3. add bundleId field
    • Operations

      db.ApplicationBundle.updateMany({}, {
      	$set: {
      		"resource.reservedTimeAfterExpired": 2678400,
          bundleId: new ObjectId("6405ffe6103ead6d468b1a17"),
      	}
      })
      
  3. Database: Region schema changes

    1. add storageConf.controlEndpoint field
    2. add databaseConf.controlConnectionUri field
  4. API: remove POST /v1/applications

    1. use POST /v1/subscriptions instead
  5. API: remove DELETE /v1/applications/:appid

    1. use DELETE v1/subscriptions instead
  6. Database: Add Subscriptions for existed applications

    1. expiredAt set to 1 month in future
    • Operations

      // write cloud function to insert subscriptions
      import cloud from '@lafjs/cloud'
      import { MongoClient, ObjectId, Db } from 'mongodb'
      
      const sys_db_uri = cloud.env.SYS_DB_URI
      // set your existed bundle id
      const bundleId = new ObjectId('6407200ca35fb4d684296d5c')
      
      export async function main(ctx: FunctionContext) {
        const client = new MongoClient(sys_db_uri)
        await client.connect()
      
        const db = client.db('sys_db')
      
        const apps = await db.collection('Application')
          .find()
          .toArray()
      
        for(let app of apps) {
          const res = await addSubscription(db, app, bundleId)
          console.log(app.appid, res)
        }
      
        return { data: 'hi, laf' }
      }
      
      async function addSubscription(db: Db, app: any, bundleId: ObjectId) {
        const sub = {
          "bundleId": bundleId,
          "appid": app.appid,
          "state": "Created",
          "phase": "Valid",
          "renewalPlan": "Manual",
          "expiredAt": new Date('2023-12-31T00:00:00.733Z'),
          "lockedAt": new Date('1970-01-01T00:00:00.000Z'),
          "createdAt": new Date(),
          "updatedAt": new Date(),
          "createdBy": app.createdBy,
          "input": {
            "name": app.name,
            "state": app.state,
            "regionId": app.regionId,
            "runtimeId": app.runtimeId
          }
        }
      
        return await db.collection('Subscription').insertOne(sub)
      }
      

New Configrations

Config phone auth provider

db.AuthProvider.updateOne({ name: "phone" }, {
	$set: {
           state: "Enabled",
          "config.alisms": {
	    "accessKeyId": "",
	    "accessKeySecret": "",
	    "api_entrypoint": "https://dysmsapi.aliyuncs.com",
	    "signName": "",
	    "templateCode": "SMS_000004"
	  }
      }
})

Add Wechat payment channel

// db.PaymentChannel.find().pretty()

db.PaymentChannel.insertOne({
  type: "WeChat",
  name: "WeChat Pay",
  spec: {
	  mchid: "",
           appid: "",
           apiV3Key: "",
           certificateSerialNumber: "",
          privateKey: "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----",
          publicKey: "----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"
  },
  state: "Active",
  createdAt: new Date(),
  updatedAt: new Date()
})