Skip to content

Commit

Permalink
Merge branch 'labring:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
bearslyricattack authored Sep 9, 2024
2 parents 12b401d + 47001c9 commit bbf5fb0
Show file tree
Hide file tree
Showing 41 changed files with 1,467 additions and 441 deletions.
10 changes: 6 additions & 4 deletions controllers/devbox/api/v1alpha1/devbox_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,12 @@ const (
)

type CommitHistory struct {
Image string `json:"image"`
Time metav1.Time `json:"time"`
Pod string `json:"pod"`
Status CommitStatus `json:"status"`
Image string `json:"image"`
Time metav1.Time `json:"time"`
Pod string `json:"pod"`
Status CommitStatus `json:"status"`
Node string `json:"node"`
ContainerID string `json:"containerID"`
}

type DevboxPhase string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2732,8 +2732,12 @@ spec:
commitHistory:
items:
properties:
containerID:
type: string
image:
type: string
node:
type: string
pod:
type: string
status:
Expand All @@ -2742,7 +2746,9 @@ spec:
format: date-time
type: string
required:
- containerID
- image
- node
- pod
- status
- time
Expand Down
6 changes: 6 additions & 0 deletions controllers/devbox/deploy/manifests/deploy.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2740,8 +2740,12 @@ spec:
commitHistory:
items:
properties:
containerID:
type: string
image:
type: string
node:
type: string
pod:
type: string
status:
Expand All @@ -2750,7 +2754,9 @@ spec:
format: date-time
type: string
required:
- containerID
- image
- node
- pod
- status
- time
Expand Down
40 changes: 33 additions & 7 deletions controllers/devbox/internal/controller/devbox_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ func (r *DevboxReconciler) updateDevboxCommitHistory(ctx context.Context, devbox
// based on pod status, update commit history status
if commitSuccess(pod.Status.Phase) {
devbox.Status.CommitHistory[i].Status = devboxv1alpha1.CommitStatusSuccess
//update node and containerId
devbox.Status.CommitHistory[i].Node = pod.Spec.NodeName
devbox.Status.CommitHistory[i].ContainerID = pod.Status.ContainerStatuses[0].ContainerID
} else {
devbox.Status.CommitHistory[i].Status = devboxv1alpha1.CommitStatusFailed
}
Expand Down Expand Up @@ -477,19 +480,42 @@ func (r *DevboxReconciler) generateDevboxPod(devbox *devboxv1alpha1.Devbox, runt
}

func (r *DevboxReconciler) syncService(ctx context.Context, devbox *devboxv1alpha1.Devbox, recLabels map[string]string) error {
expectServiceSpec := corev1.ServiceSpec{
Selector: recLabels,
Type: corev1.ServiceTypeNodePort,
Ports: []corev1.ServicePort{
var runtimeNamespace string
if devbox.Spec.RuntimeRef.Namespace != "" {
runtimeNamespace = devbox.Spec.RuntimeRef.Namespace
} else {
runtimeNamespace = devbox.Namespace
}

runtimecr := &devboxv1alpha1.Runtime{}
if err := r.Get(ctx, client.ObjectKey{Namespace: runtimeNamespace, Name: devbox.Spec.RuntimeRef.Name}, runtimecr); err != nil {
return err
}
var servicePorts []corev1.ServicePort
for _, port := range runtimecr.Spec.Config.Ports {
servicePorts = append(servicePorts, corev1.ServicePort{
Name: port.Name,
Port: port.ContainerPort,
TargetPort: intstr.FromInt32(port.ContainerPort),
Protocol: port.Protocol,
})
}
if len(servicePorts) == 0 {
//use the default value
servicePorts = []corev1.ServicePort{
{
Name: "tty",
Port: 22,
TargetPort: intstr.FromInt32(22),
Protocol: corev1.ProtocolTCP,
},
},
}
}
expectServiceSpec := corev1.ServiceSpec{
Selector: recLabels,
Type: corev1.ServiceTypeNodePort,
Ports: servicePorts,
}

service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: devbox.Name + "-svc",
Expand Down Expand Up @@ -556,7 +582,7 @@ func (r *DevboxReconciler) generateNextCommitHistory(devbox *devboxv1alpha1.Devb

func (r *DevboxReconciler) generateImageName(devbox *devboxv1alpha1.Devbox) string {
now := time.Now()
return fmt.Sprintf("%s/%s/%s:%s", r.CommitImageRegistry, devbox.Namespace, devbox.Name, now.Format("2006-01-02-150405"))
return fmt.Sprintf("%s/%s/%s:%s", r.CommitImageRegistry, devbox.Namespace, devbox.Name, rand.String(5)+"-"+now.Format("2006-01-02-150405"))
}

// SetupWithManager sets up the controller with the Manager.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (t *Client) pullManifest(username string, password string, hostName string,
return nil, err
}
req.SetBasicAuth(username, password)
req.Header.Set("Accept", "application/vnd.oci.image.manifest.v1+json")
req.Header.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")

resp, err := client.Do(req)
if err != nil {
Expand Down Expand Up @@ -127,7 +127,7 @@ func (t *Client) pushManifest(username string, password string, hostName string,
}

req.SetBasicAuth(username, password)
req.Header.Set("Content-type", "application/vnd.oci.image.manifest.v1+json")
req.Header.Set("Content-type", "application/vnd.docker.distribution.manifest.v2+json")

resp, err := client.Do(req)
if err != nil {
Expand Down
8 changes: 6 additions & 2 deletions controllers/pkg/database/cockroach/accountv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ func (c *Cockroach) GetPaymentWithID(paymentID string) (*types.Payment, error) {
return &payment, nil
}

func (c *Cockroach) GetPaymentWithLimit(ops *types.UserQueryOpts, req types.LimitReq) ([]types.Payment, types.LimitResp, error) {
func (c *Cockroach) GetPaymentWithLimit(ops *types.UserQueryOpts, req types.LimitReq, invoiced bool) ([]types.Payment, types.LimitResp, error) {
var payment []types.Payment
var total int64
var limitResp types.LimitResp
Expand All @@ -661,7 +661,11 @@ func (c *Cockroach) GetPaymentWithLimit(ops *types.UserQueryOpts, req types.Limi
return nil, limitResp, fmt.Errorf("failed to get user uid: %v", err)
}

query := c.DB.Model(&types.Payment{}).Where(types.Payment{PaymentRaw: types.PaymentRaw{UserUID: userUID}})
queryPayment := types.Payment{PaymentRaw: types.PaymentRaw{UserUID: userUID}}
if invoiced {
queryPayment.InvoicedAt = true
}
query := c.DB.Model(&types.Payment{}).Where(queryPayment)
if !req.StartTime.IsZero() {
query = query.Where("created_at >= ?", req.StartTime)
}
Expand Down
10 changes: 8 additions & 2 deletions frontend/providers/applaunchpad/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,5 +259,11 @@
"app_store": "App Store",
"sealaf": "sealaf",
"total_price_tip": "The estimated cost does not include port fees and traffic fees, and is subject to actual usage.",
"nodeports": "NodePorts"
}
"nodeports": "NodePorts",
"streaming_logs": "Streaming logs",
"within_5_minutes": "Within 5 minutes",
"within_1_hour": "Within 1 hour",
"within_1_day": "Within 1 day",
"terminated_logs": "Terminated logs",
"no_logs_for_now": "No logs for now"
}
Original file line number Diff line number Diff line change
Expand Up @@ -259,5 +259,11 @@
"sealaf": "云开发",
"app_store": "应用商店",
"total_price_tip": "预估费用不包括端口费用和流量费用,以实际使用为准",
"nodeports": "外网端口"
"nodeports": "外网端口",
"streaming_logs": "实时日志",
"within_5_minutes": "五分钟内",
"within_1_hour": "一小时内",
"within_1_day": "一天内",
"terminated_logs": "中断前",
"no_logs_for_now": "暂无日志"
}
2 changes: 2 additions & 0 deletions frontend/providers/applaunchpad/src/api/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export const getPodLogs = (data: {
podName: string;
stream: boolean;
logSize?: number;
sinceTime?: number;
previous?: boolean;
}) => POST<string>(`/api/getPodLogs`, data);

export const getPodEvents = (podName: string) =>
Expand Down
33 changes: 29 additions & 4 deletions frontend/providers/applaunchpad/src/pages/api/getPodLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
appName,
podName,
stream = false,
logSize
logSize,
previous,
sinceTime
} = req.body as {
appName: string;
podName: string;
stream: boolean;
logSize?: number;
previous?: boolean;
sinceTime?: number;
};

if (!podName) {
Expand All @@ -51,6 +55,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
});

if (!stream) {
const sinceSeconds =
sinceTime && !!!previous ? Math.floor((Date.now() - sinceTime) / 1000) : undefined;
// get pods
const { body: data } = await k8sCore.readNamespacedPodLog(
podName,
Expand All @@ -60,8 +66,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
undefined,
undefined,
undefined,
undefined,
undefined,
previous,
sinceSeconds,
logSize
);
return jsonRes(res, {
Expand All @@ -77,6 +83,21 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
res.setHeader('Cache-Control', 'no-cache, no-transform');
logStream.pipe(res);

const reqData = {
follow: true,
pretty: false,
timestamps: false,
tailLines: 1000,
previous: !!previous
} as any;
if (!reqData.previous && sinceTime) {
reqData.sinceTime = timestampToRFC3339(sinceTime);
}

if (!reqData.previous) {
res.flushHeaders();
}

streamResponse = await logs.log(
namespace,
podName,
Expand All @@ -86,7 +107,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
console.log('err', err);
destroyStream();
},
{ follow: true, pretty: false, timestamps: false, tailLines: 1000 }
reqData
);
} catch (err: any) {
jsonRes(res, {
Expand All @@ -95,3 +116,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
});
}
}

function timestampToRFC3339(timestamp: number) {
return new Date(timestamp).toISOString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const AdapterChartData: Record<
const newDataArray = data.data.result.map((item) => {
let name = item.metric.pod;
let xData = item.values.map((value) => value[0]);
let yData = item.values.map((value) => (parseFloat(value[1]) * 100).toFixed(2));
let yData = item.values.map((value) => parseFloat(value[1]).toFixed(2));
return {
name: name,
xData: xData,
Expand All @@ -27,7 +27,7 @@ const AdapterChartData: Record<
const newDataArray = data.data.result.map((item) => {
let name = item.metric.pod;
let xData = item.values.map((value) => value[0]);
let yData = item.values.map((value) => (parseFloat(value[1]) * 100).toFixed(2));
let yData = item.values.map((value) => parseFloat(value[1]).toFixed(2));
return {
name: name,
xData: xData,
Expand All @@ -40,7 +40,7 @@ const AdapterChartData: Record<
const newDataArray = data.data.result.map((item) => {
let name = item.metric.pod;
let xData = item.values.map((value) => value[0]);
let yData = item.values.map((value) => (parseFloat(value[1]) * 100).toFixed(2));
let yData = item.values.map((value) => parseFloat(value[1]).toFixed(2));
return {
name: name,
xData: xData,
Expand All @@ -53,7 +53,7 @@ const AdapterChartData: Record<
const newDataArray = data.data.result.map((item) => {
let name = item.metric.pod;
let xData = item.values.map((value) => value[0]);
let yData = item.values.map((value) => (parseFloat(value[1]) * 100).toFixed(2));
let yData = item.values.map((value) => parseFloat(value[1]).toFixed(2));
return {
name: name,
xData: xData,
Expand All @@ -66,7 +66,7 @@ const AdapterChartData: Record<
const newDataArray = data.data.result.map((item) => {
let name = item.metric.pod;
let xData = item.values.map((value) => value[0]);
let yData = item.values.map((value) => (parseFloat(value[1]) * 100).toFixed(2));
let yData = item.values.map((value) => parseFloat(value[1]).toFixed(2));
return {
name: name,
xData: xData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { AppConfigType, FileMangerType, FormSliderListType } from '@/types'
import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import type { NextApiRequest, NextApiResponse } from 'next';
import { getGpuNode } from './resourcePrice';

// todo make response type to be more specific and clear.
export type Response = {
Expand All @@ -24,7 +25,8 @@ export const defaultAppConfig: AppConfigType = {
},
common: {
guideEnabled: false,
apiEnabled: false
apiEnabled: false,
gpuEnabled: false
},
launchpad: {
ingressTlsSecretName: 'wildcard-cert',
Expand Down Expand Up @@ -66,6 +68,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const res: any = yaml.load(readFileSync(filename, 'utf-8'));
console.log(res);
global.AppConfig = res;
const gpuNodes = await getGpuNode();
global.AppConfig.common.gpuEnabled = gpuNodes.length > 0;
}
jsonRes<Response>(res, {
data: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { authSession } from '@/services/backend/auth';
import { getK8s } from '@/services/backend/kubernetes';
import { jsonRes } from '@/services/backend/response';
import { authSession } from '@/services/backend/auth';
import { UserQuotaItemType } from '@/types/user';
import Decimal from 'decimal.js';
import type { NextApiRequest, NextApiResponse } from 'next';

async function getAmount(req: NextApiRequest): Promise<{
data?: {
Expand Down Expand Up @@ -65,6 +65,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});

const quota = await getUserQuota();
const gpuEnabled = global.AppConfig.common.gpuEnabled;
const filteredQuota = gpuEnabled ? quota : quota.filter((item) => item.type !== 'gpu');

let balance = '0';
try {
Expand All @@ -84,7 +86,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
quota: UserQuotaItemType[];
}>(res, {
data: {
quota,
quota: filteredQuota,
balance
}
});
Expand Down
Loading

0 comments on commit bbf5fb0

Please sign in to comment.