@stacksjs/ts-cloud 0.16.44 → 0.16.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/{chunk-gn03w47w.js → chunk-01w4zbex.js} +1 -1
- package/dist/bin/{chunk-nmqjmx30.js → chunk-12x968en.js} +1 -1
- package/dist/bin/chunk-1xxmyx0r.js +1 -0
- package/dist/bin/{chunk-kdsgbvep.js → chunk-23m8kbwh.js} +1 -1
- package/dist/bin/{chunk-bj7ashn6.js → chunk-2gqhzn2r.js} +1 -1
- package/dist/bin/chunk-45qr2bd3.js +1 -0
- package/dist/bin/chunk-4nn00brw.js +1 -0
- package/dist/bin/{chunk-t80pxn04.js → chunk-50r8znqt.js} +6 -6
- package/dist/bin/chunk-5f1n5d80.js +1 -0
- package/dist/bin/{chunk-s64d5nw2.js → chunk-5mm6qn6m.js} +1 -1
- package/dist/bin/chunk-5xr76cms.js +1 -0
- package/dist/bin/{chunk-q40k9jvk.js → chunk-65yvjecx.js} +2 -2
- package/dist/bin/{chunk-5amvqed8.js → chunk-6y6g726g.js} +3 -3
- package/dist/bin/{chunk-f64jvh96.js → chunk-7qbxq0be.js} +2 -2
- package/dist/bin/{chunk-8z4wgqkh.js → chunk-cz2wq0tf.js} +1 -1
- package/dist/bin/chunk-d0tmmzy5.js +1 -0
- package/dist/bin/{chunk-erf79tm2.js → chunk-dawvjb7v.js} +21 -21
- package/dist/bin/{chunk-7p2va3nj.js → chunk-de69nra4.js} +1 -1
- package/dist/bin/{chunk-tf8qxy9k.js → chunk-dj03v81n.js} +20 -20
- package/dist/bin/chunk-fqghdpvr.js +1 -0
- package/dist/bin/{chunk-35x7z78g.js → chunk-frzpqsbj.js} +1 -1
- package/dist/bin/chunk-gkdr09xx.js +1 -0
- package/dist/bin/{chunk-xxe9ga9r.js → chunk-gyvkravq.js} +3 -3
- package/dist/bin/{chunk-jaexpxs8.js → chunk-her9ny96.js} +1 -1
- package/dist/bin/{chunk-3hkppc7h.js → chunk-kqxk1pds.js} +1 -1
- package/dist/bin/{chunk-hfnpjy9y.js → chunk-n2c6y0k1.js} +1 -1
- package/dist/bin/{chunk-3v2pd05g.js → chunk-nhqz2j90.js} +1 -1
- package/dist/bin/chunk-pg65zy8y.js +1 -0
- package/dist/bin/chunk-pr1dg1km.js +1 -0
- package/dist/bin/{chunk-dkf2kcsc.js → chunk-psvqpztv.js} +3 -3
- package/dist/bin/{chunk-ce1qnjs2.js → chunk-pzj1ac7x.js} +1 -1
- package/dist/bin/{chunk-gngsb689.js → chunk-q4dywv80.js} +2 -2
- package/dist/bin/{chunk-pf9dbm3b.js → chunk-q8b77zgw.js} +1 -1
- package/dist/bin/{chunk-qj6tr7bw.js → chunk-qq1f07te.js} +3 -3
- package/dist/bin/chunk-r1kg6yxp.js +1 -0
- package/dist/bin/{chunk-mgwmt2et.js → chunk-rdkr74y2.js} +2 -2
- package/dist/bin/{chunk-jh1vmant.js → chunk-rgcrsd5m.js} +1 -1
- package/dist/bin/chunk-t1mmfpn1.js +1 -0
- package/dist/bin/chunk-thph4z3k.js +1 -0
- package/dist/bin/chunk-txykq6f1.js +1 -0
- package/dist/bin/{chunk-2r9tj1ac.js → chunk-v09tfezh.js} +5 -5
- package/dist/bin/{chunk-dryvqne2.js → chunk-v7t6f8aw.js} +2 -2
- package/dist/bin/{chunk-knzje4ka.js → chunk-vjg2fymw.js} +1 -1
- package/dist/bin/chunk-vt3hjh9q.js +1 -0
- package/dist/bin/{chunk-sg8hcdev.js → chunk-w29z877b.js} +1 -1
- package/dist/bin/{chunk-7593hjcq.js → chunk-xdk0gmxt.js} +1 -1
- package/dist/bin/{chunk-fkzp9sg5.js → chunk-xe527q1k.js} +1 -1
- package/dist/bin/{chunk-9eqpnanr.js → chunk-xx9mrcfs.js} +1 -1
- package/dist/bin/{chunk-vjfwnj9z.js → chunk-ym9h629y.js} +4 -4
- package/dist/bin/{chunk-cqc4e8md.js → chunk-yp3a0j9n.js} +1 -1
- package/dist/bin/{chunk-kzpzkdpd.js → chunk-z8k9mcn5.js} +1 -1
- package/dist/bin/chunk-z8scg2vy.js +1 -0
- package/dist/bin/{chunk-pnj95hwr.js → chunk-znd507q9.js} +1 -1
- package/dist/bin/cli.js +98 -98
- package/dist/bin/dashboard-server.js +1 -1
- package/dist/{chunk-txwnpxzf.js → chunk-294kdscm.js} +1 -1
- package/dist/{chunk-a102vqez.js → chunk-vv5fmmhr.js} +1 -1
- package/dist/deploy/index.js +1 -1
- package/dist/drivers/factory.d.ts +3 -3
- package/dist/drivers/index.js +1 -1
- package/dist/fly/client.d.ts +153 -0
- package/dist/fly/deploy.d.ts +72 -0
- package/dist/fly/index.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -26
- package/dist/ui/404.html +1 -1
- package/dist/ui/accept-invitation.html +1 -1
- package/dist/ui/access-denied.html +1 -1
- package/dist/ui/account/automation.html +5 -5
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +6 -6
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +6 -6
- package/dist/ui/data/services.html +6 -6
- package/dist/ui/data/volumes.html +6 -6
- package/dist/ui/index.html +6 -6
- package/dist/ui/infrastructure/topology.html +6 -6
- package/dist/ui/integrations.html +1 -1
- package/dist/ui/operations/alerts.html +6 -6
- package/dist/ui/operations/configuration.html +6 -6
- package/dist/ui/operations/jobs.html +6 -6
- package/dist/ui/operations/maintenance.html +5 -5
- package/dist/ui/operations/observability.html +6 -6
- package/dist/ui/operations/previews.html +6 -6
- package/dist/ui/operations/queue.html +6 -6
- package/dist/ui/operations/regions.html +5 -5
- package/dist/ui/operations/releases.html +6 -6
- package/dist/ui/operations/spend.html +6 -6
- package/dist/ui/operations/workloads.html +6 -6
- package/dist/ui/security.html +1 -1
- package/dist/ui/server/actions.html +6 -6
- package/dist/ui/server/activity.html +1 -1
- package/dist/ui/server/capacity.html +6 -6
- package/dist/ui/server/database.html +6 -6
- package/dist/ui/server/deployments.html +6 -6
- package/dist/ui/server/diagnostics.html +1 -1
- package/dist/ui/server/firewall.html +6 -6
- package/dist/ui/server/fleet.html +6 -6
- package/dist/ui/server/logs.html +6 -6
- package/dist/ui/server/metrics.html +6 -6
- package/dist/ui/server/security.html +2 -2
- package/dist/ui/server/services.html +1 -1
- package/dist/ui/server/sites.html +6 -6
- package/dist/ui/server/ssh-keys.html +6 -6
- package/dist/ui/server/team.html +6 -6
- package/dist/ui/server/terminal.html +1 -1
- package/dist/ui/serverless/alarms.html +6 -6
- package/dist/ui/serverless/assets.html +2 -2
- package/dist/ui/serverless/cost.html +2 -2
- package/dist/ui/serverless/data.html +6 -6
- package/dist/ui/serverless/deployments.html +2 -2
- package/dist/ui/serverless/firewall.html +1 -1
- package/dist/ui/serverless/functions.html +6 -6
- package/dist/ui/serverless/logs.html +6 -6
- package/dist/ui/serverless/metrics.html +2 -2
- package/dist/ui/serverless/queues.html +6 -6
- package/dist/ui/serverless/secrets.html +6 -6
- package/dist/ui/serverless/traces.html +6 -6
- package/dist/ui/serverless.html +5 -5
- package/package.json +3 -3
- package/dist/bin/chunk-26rf5dy2.js +0 -1
- package/dist/bin/chunk-5khcwxhn.js +0 -1
- package/dist/bin/chunk-5nc1g18b.js +0 -1
- package/dist/bin/chunk-71ep1g7k.js +0 -1
- package/dist/bin/chunk-7fh7b8r1.js +0 -1
- package/dist/bin/chunk-7nsjehvx.js +0 -1
- package/dist/bin/chunk-bb08ms5q.js +0 -1
- package/dist/bin/chunk-g3a9a8bx.js +0 -1
- package/dist/bin/chunk-jv9qp13h.js +0 -1
- package/dist/bin/chunk-k9ate69x.js +0 -1
- package/dist/bin/chunk-mh3rgn0e.js +0 -1
- package/dist/bin/chunk-nfb3ew1v.js +0 -1
- package/dist/bin/chunk-qgqgdkg0.js +0 -1
- package/dist/bin/chunk-s77kny9g.js +0 -1
- package/dist/bin/chunk-vn05n5z6.js +0 -1
- package/dist/bin/chunk-yxpzm8ce.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunk-
|
|
1
|
+
import"./chunk-dj03v81n.js";import"./chunk-4yym8xm4.js";import"./chunk-znd507q9.js";import"./chunk-ym9h629y.js";import{cr}from"./chunk-dawvjb7v.js";import"./chunk-psvqpztv.js";import"./chunk-12x968en.js";import"./chunk-z8k9mcn5.js";import"./chunk-cz2wq0tf.js";import"./chunk-50r8znqt.js";import"./chunk-xdk0gmxt.js";import"./chunk-nhqz2j90.js";import"./chunk-q8b77zgw.js";import"./chunk-01w4zbex.js";import"./chunk-q4dywv80.js";import"./chunk-frzpqsbj.js";import"./chunk-23m8kbwh.js";import"./chunk-xx9mrcfs.js";import"./chunk-de69nra4.js";import"./chunk-yp3a0j9n.js";import"./chunk-gyvkravq.js";import"./chunk-6y6g726g.js";import"./chunk-qq1f07te.js";import"./chunk-her9ny96.js";import"./chunk-nj9x0tb8.js";import"./chunk-xe527q1k.js";import"./chunk-7qbxq0be.js";import n from"node:process";function r(o){let e=n.argv.indexOf(o);return e===-1?void 0:n.argv[e+1]}function t(o){return n.argv.includes(o)}async function i(){let o=await cr({host:r("--host")??"127.0.0.1",port:Number(r("--port")??7676),environment:r("--env"),box:t("--box"),verbose:t("--verbose")});console.log("ts-cloud Local Dashboard"),console.log(`Serving ${o.url}`),await new Promise((e)=>{let s=()=>{o.server.stop(!0),e()};n.once("SIGINT",s),n.once("SIGTERM",s)})}i();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_d,L,d,$d,Q,g,fe,p,Xt,Hd,Fi,To,jd,Wd,Jd,Al,tn,qi,nr,yl,Sl,Tl,wl}from"./chunk-c5jyzyqw.js";import{_,u}from"./chunk-hm6pwhne.js";import{me,Vt,P,qt,s,vi,Zs,Mr,nd,id,te,c,ro,Ve,Fr,sd,jt,io,od,Ur,so,Qr,Ri,Wt,ki,Bi,qe,Jt,Rd,Dd,Oi,_i,At,So,i,Li,bo,Co}from"./chunk-v3w791ze.js";import{n}from"./chunk-cgcthvq9.js";import{o}from"./chunk-bwtxb2hf.js";import{Tn}from"./chunk-j5x0qn7z.js";import{be}from"./chunk-w78e5n94.js";import{wn,eg,Is,B,w,bs,tg}from"./chunk-96vc5w8w.js";import{Se,lr,Ts,nt,W,ae,E,Ie,pr,ce,st,fr}from"./chunk-8jsf214f.js";import{J}from"./chunk-ct72f70x.js";import{v,br,Qs,Qt,Cr,mg,Ht,hg,Ag,Tc,Qe,lt,ri,O,Gt,kr}from"./chunk-
|
|
1
|
+
import{_d,L,d,$d,Q,g,fe,p,Xt,Hd,Fi,To,jd,Wd,Jd,Al,tn,qi,nr,yl,Sl,Tl,wl}from"./chunk-c5jyzyqw.js";import{_,u}from"./chunk-hm6pwhne.js";import{me,Vt,P,qt,s,vi,Zs,Mr,nd,id,te,c,ro,Ve,Fr,sd,jt,io,od,Ur,so,Qr,Ri,Wt,ki,Bi,qe,Jt,Rd,Dd,Oi,_i,At,So,i,Li,bo,Co}from"./chunk-v3w791ze.js";import{n}from"./chunk-cgcthvq9.js";import{o}from"./chunk-bwtxb2hf.js";import{Tn}from"./chunk-j5x0qn7z.js";import{be}from"./chunk-w78e5n94.js";import{wn,eg,Is,B,w,bs,tg}from"./chunk-96vc5w8w.js";import{Se,lr,Ts,nt,W,ae,E,Ie,pr,ce,st,fr}from"./chunk-8jsf214f.js";import{J}from"./chunk-ct72f70x.js";import{v,br,Qs,Qt,Cr,mg,Ht,hg,Ag,Tc,Qe,lt,ri,O,Gt,kr}from"./chunk-vv5fmmhr.js";import{S}from"./chunk-3s8dtcz8.js";import{$e}from"./chunk-varjr6np.js";import{Re}from"./chunk-fwcf0n8f.js";import{h}from"./chunk-9e4afej1.js";function An(e){let t=Dc(e.name),r=xl(e.configText);if(kw(e.configText,r.start,r.end,t))throw Error(`Site '${t}' already exists in cloud.config.ts`);let a=Gf({...e,name:t}),l=e.configText.slice(0,r.end).trimEnd(),m=e.configText.slice(r.end),f=l.endsWith("{")?`
|
|
2
2
|
`:l.endsWith(",")?`
|
|
3
3
|
|
|
4
4
|
`:`,
|
|
@@ -392,7 +392,7 @@ ${" ".repeat(t+10)}${r.remediation}`:n}).join(`
|
|
|
392
392
|
`);try{await this.exec(c.publicIp,l);continue}catch{}let m=`${Tn}/.${i}-${bo()}.tmp`;try{await this.transport.scp(c.publicIp,e.localPath,m),await this.exec(c.publicIp,sr(m,a,s))}catch(S){throw await this.exec(c.publicIp,or(m)).catch(()=>{}),S}}return{artifactRef:s}}async runRemoteDeploy(e){if(e.targets.length===0)return{success:!1,instanceCount:0,perInstance:[],error:"No targets provided"};let t=e.commands.join(`
|
|
393
393
|
`),r=[];for(let s of e.targets){if(!s.publicIp){r.push({instanceId:s.id,status:"Failed",error:"Missing address"});continue}try{let i=await this.exec(s.publicIp,t);Ir(i),r.push({instanceId:s.id,status:"Success",output:i})}catch(i){r.push({instanceId:s.id,status:"Failed",error:i.message})}}let n=r.every((s)=>s.status==="Success");return{success:n,instanceCount:e.targets.length,perInstance:r,error:n?void 0:Ut(r,"One or more SSH deploy commands failed")}}targetHost(){return this.host.host}ensureHostKey(e=this.host.host){return this.transport.ensureHostKey(e)}async preflight(e=this.host.host){let t=await this.transport.exec(e,si,{sudo:!1}),r=oi(t);return{facts:r,findings:ai(r,{user:this.host.user,profile:this.settings.profile})}}async provisionComputeInfrastructure(e){let{config:t,environment:r}=e;for(let T of Mg(t,this.settings))console.warn(`[ts-cloud] ${T}`);let n=this.host,s=p(t,r),i=await He(s,this.cwd),a=process.env[$g]==="1"&&i?.provider==="ssh"&&i.host===n.host&&i.bootstrapVersion===we,c=await this.ensureHostKey(n.host);if(c.pinnedNow)console.warn(`[ts-cloud] pinned ${n.host} host key ${c.fingerprint}`);await this.waitForSshReady(n.host);let{facts:l,findings:m}=await this.preflight(n.host);if(ci(m))throw Error(`Preflight failed for ${n.host}; refusing to bootstrap it.
|
|
394
394
|
${di(m)}`);for(let T of m)console.warn(`[ts-cloud] ${T.severity}: ${T.message}`);if(l.cloudInitPresent&&/running/i.test(l.cloudInitStatus??""))await this.waitForCloudInit(n.host);let S=l.lanIp?.trim()||(hl(n.host)!==0?n.host:void 0),b=i?.provider==="ssh"?i.bootstrappedAt:void 0;if(!a){let T=ni({config:t,environment:r,profile:this.settings.profile,facts:l,sudoUser:n.user!=="root"?n.user:void 0,lan:this.settings.lan,lanIp:S});Ir(await this.exec(n.host,T)),b=new Date().toISOString()}let y={provider:"ssh",stackName:s,host:n.host,sshUser:n.user,sshPort:n.port,hostKeyFingerprint:c.fingerprint||void 0,publicIp:this.settings.publicIp==="auto"?void 0:this.settings.publicIp,lanIp:l.lanIp||void 0,deployStoragePath:li,profile:this.settings.profile,bootstrapVersion:we,bootstrappedAt:b};await dt(s,y,this.cwd);let f=await this.getComputeOutputs();if(se(t.infrastructure?.compute)&&tn(this.settings.lan)==="local-ca")f.lanCaCertPath=Vt(),console.warn(`[ts-cloud] LAN certificate authority on ${n.host} at ${f.lanCaCertPath}. Fetch it with: scp ${n.user}@${n.host}:${f.lanCaCertPath} ./rpx-root-ca.crt`);return f}async destroyCompute(e){let t=p(e.config,e.environment),r=this.host;return console.warn(`[ts-cloud] forgot ${r.host} for ${t}; nothing was removed on the host (stop the systemd units and remove /var/ts-cloud and /etc/rpx by hand if you want it clean).`),await dt(t,{provider:"ssh",stackName:t,host:r.host,sshUser:r.user,sshPort:r.port},this.cwd).catch(()=>{}),{destroyed:[`local state for ${t}`]}}async sleep(e){await new Promise((t)=>setTimeout(t,e))}async waitForSshReady(e){let{sshIntervalMs:t,sshTimeoutMs:r}=this.bootWait,n=Date.now();do{if(await this.transport.probe(e))return;await this.sleep(t)}while(Date.now()-n<r);throw Error(`Timed out waiting for SSH on ${e} after ${r}ms`)}async waitForCloudInit(e){let{cloudInitIntervalMs:t,cloudInitTimeoutMs:r}=this.bootWait,n=Date.now();while(Date.now()-n<r){try{let s=await this.transport.exec(e,"if command -v cloud-init >/dev/null 2>&1; then cloud-init status --long 2>/dev/null || true; else echo 'status: done'; fi",{sudo:!1});if(/status:\s*error/.test(s))throw Error(`cloud-init reported an error on ${e}:
|
|
395
|
-
${s}`);if(/status:\s*(?:done|degraded)/.test(s))return}catch(s){if(s instanceof Error&&/cloud-init reported an error/.test(s.message))throw s}await this.sleep(t)}throw Error(`Timed out waiting for cloud-init to finish on ${e} after ${r}ms`)}}function O(e){if(Dc())return new Vs;switch(e.provider??fe(e.config)){case"aws":return new vr({region:e.config.project.region});case"hetzner":return new Te({apiToken:e.config.hetzner?.apiToken,allowStateOnly:Boolean(e.config.cloud?.attachTo),sshPrivateKeyPath:e.config.hetzner?.sshPrivateKeyPath,sshPublicKeyPath:e.config.hetzner?.sshPublicKeyPath,sshUser:e.config.hetzner?.sshUser,location:e.config.hetzner?.location});case"ssh":return new Nr({hosts:e.config.ssh?.hosts,hostKey:e.config.ssh?.hostKey,sudo:e.config.ssh?.sudo,profile:e.config.ssh?.profile,publicIp:e.config.ssh?.publicIp,lan:e.config.ssh?.lan});default:throw Error(`Unknown cloud provider: ${e.provider??fe(e.config)}`)}}class js{drivers=new Map;getDriver(e,t){let r=t??fe(e),n=`${r}:${e.project.slug}:${e.project.region||"default"}`,s=this.drivers.get(n);if(s)return s;let i=O({config:e,provider:r});return this.drivers.set(n,i),i}}var Fg=new js;var Ug="/var/lib/ts-cloud/bootstrap.sh",Qg={"raspberry-pi-os":"bootfs",ubuntu:"system-boot"},vl=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,yl=/^[a-z_][a-z0-9_-]{0,31}$/,$l=/^[A-Z]{2}$/;function le(e){return JSON.stringify(e)}function bl(e){if(!vl.test(e.hostname))throw Error(`Invalid hostname '${e.hostname}': use lowercase letters, digits and hyphens.`);if(!yl.test(e.user))throw Error(`Invalid user '${e.user}': use a lowercase Unix user name.`);let t=e.publicKey.trim();if(!t||t.includes(`
|
|
395
|
+
${s}`);if(/status:\s*(?:done|degraded)/.test(s))return}catch(s){if(s instanceof Error&&/cloud-init reported an error/.test(s.message))throw s}await this.sleep(t)}throw Error(`Timed out waiting for cloud-init to finish on ${e} after ${r}ms`)}}function O(e){if(Dc())return new Vs;switch(e.provider??fe(e.config)){case"aws":return new vr({region:e.config.project.region});case"hetzner":return new Te({apiToken:e.config.hetzner?.apiToken,allowStateOnly:Boolean(e.config.cloud?.attachTo),sshPrivateKeyPath:e.config.hetzner?.sshPrivateKeyPath,sshPublicKeyPath:e.config.hetzner?.sshPublicKeyPath,sshUser:e.config.hetzner?.sshUser,location:e.config.hetzner?.location});case"ssh":return new Nr({hosts:e.config.ssh?.hosts,hostKey:e.config.ssh?.hostKey,sudo:e.config.ssh?.sudo,profile:e.config.ssh?.profile,publicIp:e.config.ssh?.publicIp,lan:e.config.ssh?.lan});case"fly":throw Error("Fly.io has no box to provision or reach over SSH: deploy it with deployToFly() from @stacksjs/ts-cloud.");default:throw Error(`Unknown cloud provider: ${e.provider??fe(e.config)}`)}}class js{drivers=new Map;getDriver(e,t){let r=t??fe(e),n=`${r}:${e.project.slug}:${e.project.region||"default"}`,s=this.drivers.get(n);if(s)return s;let i=O({config:e,provider:r});return this.drivers.set(n,i),i}}var Fg=new js;var Ug="/var/lib/ts-cloud/bootstrap.sh",Qg={"raspberry-pi-os":"bootfs",ubuntu:"system-boot"},vl=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,yl=/^[a-z_][a-z0-9_-]{0,31}$/,$l=/^[A-Z]{2}$/;function le(e){return JSON.stringify(e)}function bl(e){if(!vl.test(e.hostname))throw Error(`Invalid hostname '${e.hostname}': use lowercase letters, digits and hyphens.`);if(!yl.test(e.user))throw Error(`Invalid user '${e.user}': use a lowercase Unix user name.`);let t=e.publicKey.trim();if(!t||t.includes(`
|
|
396
396
|
`)||!/^(?:ssh|ecdsa|sk)-/.test(t))throw Error("publicKey must be one public key line, e.g. the contents of ~/.ssh/id_ed25519.pub.");if(e.wifi){if(!e.wifi.ssid)throw Error("wifi.ssid is required.");if(!e.wifi.passphrase)throw Error("wifi.passphrase is required.");if(!$l.test(e.wifi.country))throw Error(`wifi.country must be a two-letter regulatory domain such as DE or US, not '${e.wifi.country}'.`)}}function Tl(e,t){let r=[`hostname: ${le(e.hostname)}`,"manage_etc_hosts: true","users:",` - name: ${le(e.user)}`," ssh_authorized_keys:",` - ${le(e.publicKey.trim())}`,` sudo: ${le("ALL=(ALL) NOPASSWD:ALL")}`," shell: /bin/bash"," lock_passwd: true","ssh_pwauth: false"];if(e.timezone)r.push(`timezone: ${le(e.timezone)}`);if(e.locale)r.push(`locale: ${le(e.locale)}`);if(r.push("package_update: true"),t==="raspberry-pi-os")r.push("rpi:"," enable_ssh: true"," interfaces:"," spi: false"," i2c: false"," onewire: false"," remote_gpio: false"," serial:"," console: false"," hardware: false");return`${r.join(`
|
|
397
397
|
`)}
|
|
398
398
|
`}function wl(e){let t=["version: 2","ethernets:"," eth0:"," match:",` name: ${le("e*")}`," dhcp4: true"," dhcp6: true"," optional: true"];if(e.wifi)t.push("wifis:"," wlan0:"," dhcp4: true"," dhcp6: true"," optional: true",` regulatory-domain: ${le(e.wifi.country)}`," access-points:",` ${le(e.wifi.ssid)}:`,` password: ${le(e.wifi.passphrase)}`);return`${t.join(`
|
package/dist/deploy/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{An,yn,Nu,ds,ku,Bu,xu,Ba,Ou,_u,Gf,Lu,C,$u,ls,xe,Mu,Fu,IS,Uu,Qu,Hu,Gu,Vu,Vf,bS,CS,ES,qf,jf,vS,TS,zf,Kf,wS,us,cr,xa,Sn,In,dr,rt,Pt,gs,Wf,bn,qu,ju,Oa,ms,En,fs,Ka}from"../chunk-
|
|
1
|
+
import{An,yn,Nu,ds,ku,Bu,xu,Ba,Ou,_u,Gf,Lu,C,$u,ls,xe,Mu,Fu,IS,Uu,Qu,Hu,Gu,Vu,Vf,bS,CS,ES,qf,jf,vS,TS,zf,Kf,wS,us,cr,xa,Sn,In,dr,rt,Pt,gs,Wf,bn,qu,ju,Oa,ms,En,fs,Ka}from"../chunk-294kdscm.js";import{Wa,vn,Tn,hs,As,ys,Ss,Ja,Xa}from"../chunk-j5x0qn7z.js";import{Ya}from"../chunk-96vc5w8w.js";import"../chunk-8jsf214f.js";import"../chunk-w78e5n94.js";import"../chunk-3s8dtcz8.js";import"../chunk-varjr6np.js";import"../chunk-ct72f70x.js";import"../chunk-gp9tkznp.js";import"../chunk-97gre81w.js";import{lg,fc,Ce,hc,Un,ug,Ac,Uc,zs,Qc,Gt,fi,Ks}from"../chunk-vv5fmmhr.js";import"../chunk-fwcf0n8f.js";import"../chunk-9e4afej1.js";import"../chunk-bwtxb2hf.js";import"../chunk-cgcthvq9.js";import{pt,eA,Kc,bi,Ci,Ei,yp}from"../chunk-1w9v8g26.js";import{_,_r,Lr,Wc,Xs,u,tA,Sp,Ip,nI,iI}from"../chunk-hm6pwhne.js";import"../chunk-v3w791ze.js";import"../chunk-c5jyzyqw.js";import"../chunk-x2pxtfk0.js";export{eA as DEFAULT_SITE_PORT_RANGE,pt as HOST_SITES_DIR,hc as IPV6_EXCLUDED_HOST_LABELS,Uc as MANAGEMENT_DASHBOARD_SITE,An as addSiteToCloudConfig,yp as allocateSitePorts,wS as buildAndPushContainerImage,Ya as buildAndPushServerlessImage,cr as buildFunctionEnv,Ci as buildHostSitePortsScript,Ks as buildManagementDashboardArtifact,Pt as buildServerTopology,gs as buildServerlessTopology,Wf as buildTopology,Oa as collectEgressMetrics,lg as collectServerDnsDomains,Kf as createContainerImageDependencies,qf as createExistingStaticFullStackDependencies,Vf as createStaticApiOriginDependencies,En as dashboardActions,zs as dashboardCredentialsFile,Mu as dashboardPageRoutes,Gu as deleteFailoverReplicaBuckets,Ja as deleteStaticSite,vS as deployExistingStaticFullStack,xa as deployServerlessApp,iI as deployShipsFiles,Vu as deploySite,bS as deployStaticApiOrigin,As as deployStaticSite,Xa as deployStaticSiteFull,vn as deployStaticSiteWithExternalDns,Tn as deployStaticSiteWithExternalDnsFull,qu as egressReportMetrics,C as ensureDashboardActor,Uu as ensureFailoverReplicaBuckets,fi as ensureManagementDashboard,TS as estimateExistingStaticFullStackMonthlyCost,ES as estimateStaticApiOriginMonthlyCost,ju as fetchEgressReport,jf as generateExistingStaticFullStackTemplate,Wa as generateExternalDnsStaticSiteTemplate,hs as generateStaticSiteTemplate,Qu as grantFailoverReplicaAccess,tA as hasComputeConfigured,Wc as hasProxyUpstream,zf as hashContainerContext,Un as hostAcceptsIpv6,us as infraEnvFromOutputs,$u as initializeDashboardControlPlane,Ss as invalidateCache,_r as isPhpSite,Ba as isValidHostname,Ce as normalizePublicIpv6,bi as occupiedHostPorts,Ei as parseHostSiteFragments,Kc as parseUpstreamPort,ug as reconcileAddressRecords,Sn as redeployServerlessApp,yn as removeSiteFromCloudConfig,fc as removeStaleServerAddressRecords,Ou as renderAliasesValue,xu as renderEnvValue,_u as renderRedirectsValue,Gf as renderSiteSnippet,ku as renderSslValue,Bu as renderStringValue,fs as resolveDashboardAction,Qc as resolveDashboardAuth,bn as resolveDashboardData,Fu as resolveLegacyDashboardRoute,Lr as resolveProxyUpstreams,Xs as resolveSiteDeployTarget,u as resolveSiteKind,Gt as resolveUiSource,In as rollbackServerlessApp,IS as routesForDashboard,rt as runRemoteCommand,ms as sanitizeCloudConfig,Hu as seedFailoverReplicas,Lu as setAttachToInCloudConfig,dr as setMaintenance,ds as setSitePropertyInCloudConfig,Ip as shipsARelease,nI as shipsToBucket,_ as siteInstallBase,Ka as startLocalDashboardServer,ls as synchronizeDashboardUsers,xe as trackDashboardOperation,Nu as updateSiteInCloudConfig,ys as uploadStaticFiles,Sp as validateDeploymentConfig,Ac as verifyAddressRecord,CS as verifyStaticApiOrigin};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { CloudConfig, CloudDriver,
|
|
1
|
+
import type { CloudConfig, CloudDriver, DeployProviderName } from '@ts-cloud/core';
|
|
2
2
|
export interface CreateCloudDriverOptions {
|
|
3
3
|
config: CloudConfig;
|
|
4
|
-
provider?:
|
|
4
|
+
provider?: DeployProviderName;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Create a cloud infrastructure driver from configuration.
|
|
@@ -16,6 +16,6 @@ export declare function createCloudDriver(options: CreateCloudDriverOptions): Cl
|
|
|
16
16
|
*/
|
|
17
17
|
export declare class CloudDriverFactory {
|
|
18
18
|
private drivers;
|
|
19
|
-
getDriver(config: CloudConfig, provider?:
|
|
19
|
+
getDriver(config: CloudConfig, provider?: DeployProviderName): CloudDriver;
|
|
20
20
|
}
|
|
21
21
|
export declare const cloudDrivers: CloudDriverFactory;
|
package/dist/drivers/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Qn,Ft,Ir,Ut,Hn,Gn,Vn,qn,fg,yc,Y,Er,gh,jn,Sc,Ee,ve,Fe,x,vr,zn,Tr,pe,Ic,Kn,bc,Wn,Cc,wr,ph,mh,yg,Sg,fh,hh,Ah,Rr,Jn,Ig,Gs,Xn,Yn,Zn,ei,ti,Ec,vc,Dr,wc,Ue,Z,Rc,ct,Qe,He,dt,Te,Vs,Dc,bg,Cg,Pc,Eg,lt,ri,Nc,vg,Tg,kc,Pr,we,Bc,wg,Rg,qs,ni,ut,Dg,Pg,Ng,kg,Bg,xg,Og,_g,Lg,ii,si,oi,ai,ci,di,li,$g,Mg,Nr,O,js,Fg,Ug,Qg,xc,Hg,Gg,yh,Oc,Sh,Ih,Vg,qg,bh,Ch,Eh,_c,jg,vh,Th,wh,ui,gi,pi,mi,Lc,$c,Mc,Fc,Rh,Ws,Hc,hi,Gc,zg,Kg,Wg,Dh}from"../chunk-
|
|
1
|
+
import{Qn,Ft,Ir,Ut,Hn,Gn,Vn,qn,fg,yc,Y,Er,gh,jn,Sc,Ee,ve,Fe,x,vr,zn,Tr,pe,Ic,Kn,bc,Wn,Cc,wr,ph,mh,yg,Sg,fh,hh,Ah,Rr,Jn,Ig,Gs,Xn,Yn,Zn,ei,ti,Ec,vc,Dr,wc,Ue,Z,Rc,ct,Qe,He,dt,Te,Vs,Dc,bg,Cg,Pc,Eg,lt,ri,Nc,vg,Tg,kc,Pr,we,Bc,wg,Rg,qs,ni,ut,Dg,Pg,Ng,kg,Bg,xg,Og,_g,Lg,ii,si,oi,ai,ci,di,li,$g,Mg,Nr,O,js,Fg,Ug,Qg,xc,Hg,Gg,yh,Oc,Sh,Ih,Vg,qg,bh,Ch,Eh,_c,jg,vh,Th,wh,ui,gi,pi,mi,Lc,$c,Mc,Fc,Rh,Ws,Hc,hi,Gc,zg,Kg,Wg,Dh}from"../chunk-vv5fmmhr.js";import"../chunk-fwcf0n8f.js";import"../chunk-9e4afej1.js";import"../chunk-bwtxb2hf.js";import"../chunk-cgcthvq9.js";import"../chunk-hm6pwhne.js";import"../chunk-c5jyzyqw.js";import"../chunk-x2pxtfk0.js";export{Fc as AwsBoxProvisioner,vr as AwsDriver,Qg as BOOT_PARTITION_LABEL,js as CloudDriverFactory,Sg as DEFAULT_HOST_CLEANUP_ESCALATED,hh as DEFAULT_HOST_CLEANUP_HIGH_WATER_PERCENT,fh as DEFAULT_HOST_CLEANUP_LOW_WATER_PERCENT,yg as DEFAULT_HOST_CLEANUP_RETENTION,Ah as DEFAULT_HOST_CLEANUP_SCHEDULE,Gn as DEFAULT_RPX_CERTS_DIR,Ug as FIRST_BOOT_SCRIPT_PATH,wr as HOST_ARTIFACT_CACHE_DIR,ph as HOST_CLEANUP_SCRIPT_PATH,mh as HOST_CLEANUP_UNIT,Mc as HetznerBoxProvisioner,Dr as HetznerClient,Te as HetznerDriver,Rc as LEGACY_DRIVER_STATE_DIR,Vs as LocalBoxDriver,Kg as MANAGED_CACHE_POLICY_DISABLED,zg as MANAGED_CACHE_POLICY_OPTIMIZED,Wg as MANAGED_ORIGIN_REQUEST_POLICY_ALL_VIEWER,Rg as RASPBERRY_PI_DEFAULT_SWAP_GB,Cc as REMOTE_SCRIPT_RUNNER,jn as RPX_DIR,Sc as RPX_LAUNCHER_PATH,Ee as RPX_SERVICE_NAME,Bc as SSH_BOOTSTRAP_MARKER_DIR,we as SSH_BOOTSTRAP_VERSION,ut as SSH_DEFAULTS,li as SSH_DEPLOY_STORAGE_PATH,bg as SSH_INSECURE_HOST_KEY_OPTS,Cg as SSH_KEEPALIVE_OPTS,si as SSH_PREFLIGHT_SCRIPT,$g as SSH_SKIP_BOOTSTRAP_ENV,Nr as SshDriver,Pr as SystemSshTransport,Lc as UBUNTU_2404_AMI_PARAM,wh as acquireResizeLock,bh as applyHetznerHostOptimization,qs as assertArchSupported,Mg as assertSshComputeConfig,Ec as buildAwsArtifactFetch,$c as buildBoxUserData,Dh as buildCloudFrontOriginConfig,xc as buildCloudInitFirstBoot,qg as buildHetznerHostOptimizationScript,Xn as buildHostCleanupDeployScript,Ig as buildHostCleanupExecutable,Gs as buildHostCleanupInstallScript,Jn as buildHostCleanupScript,vc as buildLocalArtifactFetch,Y as buildRpxConfig,Fe as buildRpxFragmentRefreshScript,Er as buildRpxLbConfig,ve as buildRpxProvisionScript,Eg as buildScpArgsFor,Zn as buildSiteDeployScript,zn as buildSshArgs,Pc as buildSshArgsFor,ni as buildSshBootstrapScript,ei as buildStaticSiteDeployScript,Fg as cloudDrivers,Ch as collectHetznerHostOptimizationReport,Oc as collectHetznerResizeManifest,Rh as createBoxProvisioner,O as createCloudDriver,Hc as deployAllComputeSites,Ws as deploySiteRelease,yc as deriveRouteId,Qn as describeScriptSyntaxError,ct as driverStateDir,Qe as driverStatePath,gi as ensureFirewall,pi as ensureServer,ui as ensureSshKey,ai as evaluatePreflight,yh as executeHetznerServerResize,Tg as findKnownHostKey,di as formatPreflightFindings,Ft as formatSshFailure,qn as gatewayHostnames,x as generateUbuntuAppCloudInit,Vn as hasAutoWwwVariant,Dc as isBoxMode,Gg as isHetznerCapacityError,Hn as isLocalDatabase,vg as knownHostsLine,Nc as knownHostsToken,fg as normalizeRoutePath,Ue as normalizeSshPublicKey,oi as parsePreflightFacts,Hg as planHetznerServerResize,ci as preflightFailed,Sh as prepareHetznerResize,He as readDriverState,vh as readResizeCheckpoint,ti as releaseTarballTmpPath,hi as reloadRpxGateway,Wn as remoteScriptRunner,gh as renderRpxLauncher,Gc as renewRpxCertificates,_c as resizeCheckpointPath,jg as resizeLockPath,Yn as resolveExecStart,wc as resolveHetznerApiToken,Vg as resolveHetznerHostOptimizationPlan,Rr as resolveHostCleanupConfig,Bg as resolveSshHostKeyPolicy,Dg as resolveSshHosts,Lg as resolveSshLan,Ng as resolveSshPort,kg as resolveSshPrivateKeyPath,Og as resolveSshProfile,_g as resolveSshPublicIp,ii as resolveSshSettings,xg as resolveSshSudo,Pg as resolveSshUser,ri as scanHostKey,Ic as scpUpload,mi as serverPublicIpv4,wg as sshBootstrapMarkerPath,Tr as sshExec,pe as sshExecOrThrow,lt as sshHostKeyFingerprint,kc as sshKnownHostsPath,Ut as summarizeRemoteFailures,Ir as surfaceRemoteNotices,Eh as verifyHetznerHostOptimization,Ih as verifyHetznerResize,bc as waitForCloudInit,Kn as waitForSsh,Z as wrapCloudInitUserData,dt as writeDriverState,Th as writeResizeCheckpoint};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fly.io API client, on the Machines REST API: apps, Machines, leases,
|
|
3
|
+
* volumes, secrets, IP assignments and certificates. Paths and payloads follow
|
|
4
|
+
* Fly's API reference and its own Go client (superfly/fly-go `flaps`), which
|
|
5
|
+
* flyctl itself uses - IP allocation and certificates moved there from the
|
|
6
|
+
* GraphQL API.
|
|
7
|
+
*
|
|
8
|
+
* @see https://docs.fly.io/machines/api/
|
|
9
|
+
*/
|
|
10
|
+
export declare const FLY_MACHINES_API = "https://api.machines.dev/v1";
|
|
11
|
+
export declare class FlyApiError extends Error {
|
|
12
|
+
readonly status: number;
|
|
13
|
+
readonly path: string;
|
|
14
|
+
constructor(message: string, status: number, path: string);
|
|
15
|
+
}
|
|
16
|
+
export interface FlyApp {
|
|
17
|
+
id?: string;
|
|
18
|
+
name: string;
|
|
19
|
+
organization?: {
|
|
20
|
+
slug?: string;
|
|
21
|
+
};
|
|
22
|
+
status?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface FlyService {
|
|
25
|
+
protocol: 'tcp' | 'udp';
|
|
26
|
+
internal_port: number;
|
|
27
|
+
ports: Array<{
|
|
28
|
+
port: number;
|
|
29
|
+
handlers: string[];
|
|
30
|
+
force_https?: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
autostop?: 'off' | 'stop' | 'suspend';
|
|
33
|
+
autostart?: boolean;
|
|
34
|
+
min_machines_running?: number;
|
|
35
|
+
checks?: Array<{
|
|
36
|
+
type: 'http' | 'tcp';
|
|
37
|
+
interval?: string;
|
|
38
|
+
timeout?: string;
|
|
39
|
+
grace_period?: string;
|
|
40
|
+
method?: string;
|
|
41
|
+
path?: string;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
export interface FlyMachineConfig {
|
|
45
|
+
image: string;
|
|
46
|
+
env?: Record<string, string>;
|
|
47
|
+
guest?: {
|
|
48
|
+
cpu_kind: 'shared' | 'performance';
|
|
49
|
+
cpus: number;
|
|
50
|
+
memory_mb: number;
|
|
51
|
+
};
|
|
52
|
+
services?: FlyService[];
|
|
53
|
+
mounts?: Array<{
|
|
54
|
+
volume: string;
|
|
55
|
+
path: string;
|
|
56
|
+
}>;
|
|
57
|
+
restart?: {
|
|
58
|
+
policy: 'no' | 'always' | 'on-failure';
|
|
59
|
+
max_retries?: number;
|
|
60
|
+
};
|
|
61
|
+
metadata?: Record<string, string>;
|
|
62
|
+
}
|
|
63
|
+
export interface FlyMachine {
|
|
64
|
+
id: string;
|
|
65
|
+
name?: string;
|
|
66
|
+
state: string;
|
|
67
|
+
region: string;
|
|
68
|
+
instance_id?: string;
|
|
69
|
+
config: FlyMachineConfig;
|
|
70
|
+
}
|
|
71
|
+
export interface FlyVolume {
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
region: string;
|
|
75
|
+
size_gb: number;
|
|
76
|
+
attached_machine_id?: string | null;
|
|
77
|
+
state?: string;
|
|
78
|
+
}
|
|
79
|
+
export type FlyIpType = 'v4' | 'v6' | 'shared_v4' | 'private_v6';
|
|
80
|
+
export interface FlyIpAssignment {
|
|
81
|
+
ip: string;
|
|
82
|
+
region?: string;
|
|
83
|
+
shared?: boolean;
|
|
84
|
+
egress?: boolean;
|
|
85
|
+
}
|
|
86
|
+
/** The kind of a listed address, read as fly-go reads it. */
|
|
87
|
+
export declare function flyIpType(assignment: FlyIpAssignment): FlyIpType;
|
|
88
|
+
export interface FlyCertificate {
|
|
89
|
+
hostname: string;
|
|
90
|
+
configured?: boolean;
|
|
91
|
+
status?: string;
|
|
92
|
+
/** The records the hostname needs for the certificate to be issued. */
|
|
93
|
+
dns_requirements?: {
|
|
94
|
+
a?: string[];
|
|
95
|
+
aaaa?: string[];
|
|
96
|
+
cname?: string;
|
|
97
|
+
acme_challenge?: {
|
|
98
|
+
name: string;
|
|
99
|
+
target: string;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export interface FlyClientOptions {
|
|
104
|
+
/** `FLY_API_TOKEN`: a deploy or org token. */
|
|
105
|
+
token: string;
|
|
106
|
+
fetch?: typeof fetch;
|
|
107
|
+
}
|
|
108
|
+
export declare class FlyClient {
|
|
109
|
+
private readonly token;
|
|
110
|
+
private readonly fetch;
|
|
111
|
+
constructor(options: FlyClientOptions);
|
|
112
|
+
private rest;
|
|
113
|
+
/** The app, or null when there is none by that name. */
|
|
114
|
+
getApp(name: string): Promise<FlyApp | null>;
|
|
115
|
+
createApp(name: string, org: string): Promise<FlyApp>;
|
|
116
|
+
listMachines(app: string): Promise<FlyMachine[]>;
|
|
117
|
+
createMachine(app: string, input: {
|
|
118
|
+
region: string;
|
|
119
|
+
config: FlyMachineConfig;
|
|
120
|
+
name?: string;
|
|
121
|
+
min_secrets_version?: number;
|
|
122
|
+
}): Promise<FlyMachine>;
|
|
123
|
+
/** Update a Machine's config. `nonce` is the lease the update is made under. */
|
|
124
|
+
updateMachine(app: string, id: string, input: {
|
|
125
|
+
config: FlyMachineConfig;
|
|
126
|
+
min_secrets_version?: number;
|
|
127
|
+
}, nonce: string): Promise<FlyMachine>;
|
|
128
|
+
/** Take a Machine's lease, so no other deploy updates it meanwhile. Returns the nonce. */
|
|
129
|
+
acquireLease(app: string, id: string, ttlSeconds?: number): Promise<string>;
|
|
130
|
+
releaseLease(app: string, id: string, nonce: string): Promise<void>;
|
|
131
|
+
/** Wait for a Machine to reach a state, up to `timeoutSeconds` (Fly allows up to 60 per call). */
|
|
132
|
+
waitForState(app: string, id: string, state: 'started' | 'stopped', options?: {
|
|
133
|
+
instanceId?: string;
|
|
134
|
+
timeoutSeconds?: number;
|
|
135
|
+
}): Promise<void>;
|
|
136
|
+
listVolumes(app: string): Promise<FlyVolume[]>;
|
|
137
|
+
createVolume(app: string, input: {
|
|
138
|
+
name: string;
|
|
139
|
+
region: string;
|
|
140
|
+
size_gb: number;
|
|
141
|
+
}): Promise<FlyVolume>;
|
|
142
|
+
/**
|
|
143
|
+
* Set secrets, leaving the app's others alone. Returns the secrets version,
|
|
144
|
+
* which a Machine created or updated after it must be given as
|
|
145
|
+
* `min_secrets_version` to be sure of seeing them.
|
|
146
|
+
*/
|
|
147
|
+
setSecrets(app: string, values: Record<string, string>): Promise<number>;
|
|
148
|
+
listIpAssignments(app: string): Promise<FlyIpAssignment[]>;
|
|
149
|
+
/** Assign an address. A shared IPv4 is the organization's, shared with its other apps. */
|
|
150
|
+
assignIp(app: string, type: 'v6' | 'shared_v4' | 'v4'): Promise<FlyIpAssignment>;
|
|
151
|
+
/** Request a Let's Encrypt certificate for a custom hostname, or report the one requested before. */
|
|
152
|
+
requestCertificate(app: string, hostname: string): Promise<FlyCertificate>;
|
|
153
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { CloudConfig } from '@ts-cloud/core';
|
|
2
|
+
import type { FlyCertificate, FlyClient, FlyIpAssignment, FlyMachineConfig } from './client';
|
|
3
|
+
/**
|
|
4
|
+
* Deploy an app to Fly.io Machines (stacksjs/stacks#1044).
|
|
5
|
+
*
|
|
6
|
+
* A Fly app runs a container image on Machines: there is no box to provision
|
|
7
|
+
* and nothing to reach over SSH. A deploy converges the app on the config:
|
|
8
|
+
*
|
|
9
|
+
* 1. the app exists in the organization
|
|
10
|
+
* 2. the app's secrets are set, and their version noted, so every Machine
|
|
11
|
+
* started or updated after this sees them
|
|
12
|
+
* 3. it has a dedicated IPv6 and a shared IPv4, so `<app>.fly.dev` answers
|
|
13
|
+
* 4. each configured region runs `count` Machines on the new image: an
|
|
14
|
+
* existing one is updated in place under its lease and waited on before
|
|
15
|
+
* the next, so a rollout that fails stops with the rest still serving; a
|
|
16
|
+
* missing one is created, with its own volume when one is configured
|
|
17
|
+
* 5. each custom hostname has a certificate requested
|
|
18
|
+
*
|
|
19
|
+
* It never destroys anything. Machines beyond the configured count, or in a
|
|
20
|
+
* region no longer configured, are reported, not removed: a Machine can hold
|
|
21
|
+
* the only copy of a volume's data.
|
|
22
|
+
*/
|
|
23
|
+
export interface FlyDeployOptions {
|
|
24
|
+
app: string;
|
|
25
|
+
org: string;
|
|
26
|
+
/** The image to run, already pushed: `registry.fly.io/<app>:<tag>`. */
|
|
27
|
+
image: string;
|
|
28
|
+
regions: string[];
|
|
29
|
+
count: number;
|
|
30
|
+
internalPort: number;
|
|
31
|
+
healthPath: string;
|
|
32
|
+
vm: {
|
|
33
|
+
cpuKind: 'shared' | 'performance';
|
|
34
|
+
cpus: number;
|
|
35
|
+
memoryMb: number;
|
|
36
|
+
};
|
|
37
|
+
volume?: {
|
|
38
|
+
name: string;
|
|
39
|
+
sizeGb: number;
|
|
40
|
+
path: string;
|
|
41
|
+
};
|
|
42
|
+
autoStop: boolean;
|
|
43
|
+
/** Plain environment, visible in the Machine config. */
|
|
44
|
+
env: Record<string, string>;
|
|
45
|
+
/** Set as Fly secrets: encrypted at rest and never in the Machine config. */
|
|
46
|
+
secrets: Record<string, string>;
|
|
47
|
+
hostnames: string[];
|
|
48
|
+
/** The release this deploy is of (a commit sha), recorded on each Machine. */
|
|
49
|
+
release: string;
|
|
50
|
+
}
|
|
51
|
+
export interface FlyDeployResult {
|
|
52
|
+
app: string;
|
|
53
|
+
url: string;
|
|
54
|
+
createdApp: boolean;
|
|
55
|
+
created: string[];
|
|
56
|
+
updated: string[];
|
|
57
|
+
/** Machines the config no longer accounts for, left running. */
|
|
58
|
+
untouched: string[];
|
|
59
|
+
ips: FlyIpAssignment[];
|
|
60
|
+
certificates: FlyCertificate[];
|
|
61
|
+
}
|
|
62
|
+
/** The deploy options a `cloud.provider: 'fly'` config describes, defaults filled in. */
|
|
63
|
+
export declare function flyDeployOptions(config: CloudConfig, input: {
|
|
64
|
+
environment: string;
|
|
65
|
+
image: string;
|
|
66
|
+
release: string;
|
|
67
|
+
env?: Record<string, string>;
|
|
68
|
+
secrets?: Record<string, string>;
|
|
69
|
+
}): FlyDeployOptions;
|
|
70
|
+
/** The Machine config a deploy runs, before any volume is attached. */
|
|
71
|
+
export declare function flyMachineConfig(options: FlyDeployOptions): FlyMachineConfig;
|
|
72
|
+
export declare function deployToFly(client: FlyClient, options: FlyDeployOptions, log?: (line: string) => void): Promise<FlyDeployResult>;
|