diff --git a/smarketing-ai/app.py b/smarketing-ai/app.py index 218c44d..dadd215 100644 --- a/smarketing-ai/app.py +++ b/smarketing-ai/app.py @@ -45,7 +45,7 @@ def create_app(): # ===== 새로운 API 엔드포인트 ===== - @app.route('/api/ai/sns', methods=['GET']) + @app.route('/api/ai/sns', methods=['POST']) def generate_sns_content(): """ SNS 게시물 생성 API (새로운 요구사항) diff --git a/smarketing-ai/deployment/Jenkinsfile b/smarketing-ai/deployment/Jenkinsfile index 8e07c93..e55f855 100644 --- a/smarketing-ai/deployment/Jenkinsfile +++ b/smarketing-ai/deployment/Jenkinsfile @@ -1,5 +1,3 @@ -// smarketing-backend/smarketing-ai/deployment/Jenkinsfile - def PIPELINE_ID = "${env.BUILD_NUMBER}" def getImageTag() { @@ -13,184 +11,166 @@ podTemplate( serviceAccount: 'jenkins', containers: [ containerTemplate(name: 'podman', image: "mgoltzsche/podman", ttyEnabled: true, command: 'cat', privileged: true), - containerTemplate(name: 'git', image: 'alpine/git:latest', command: 'cat', ttyEnabled: true) + containerTemplate(name: 'azure-cli', image: 'hiondal/azure-kubectl:latest', command: 'cat', ttyEnabled: true), + containerTemplate(name: 'envsubst', image: "hiondal/envsubst", command: 'sleep', args: '1h') ], volumes: [ - emptyDirVolume(mountPath: '/run/podman', memory: false) + emptyDirVolume(mountPath: '/run/podman', memory: false), + emptyDirVolume(mountPath: '/root/.azure', memory: false) ] ) { node(PIPELINE_ID) { def props def imageTag = getImageTag() - - // Manifest Repository 설정 - def MANIFEST_REPO = 'https://github.com/won-ktds/smarketing-manifest.git' - def MANIFEST_CREDENTIAL_ID = 'github-credentials-smarketing' + def manifest = "deploy.yaml" + def namespace - try { - stage("Get Source") { - checkout scm - - // smarketing-ai 하위에 있는 설정 파일 읽기 - props = readProperties file: "smarketing-ai/deployment/deploy_env_vars" + stage("Get Source") { + checkout scm + props = readProperties file: "smarketing-ai/deployment/deploy_env_vars" + namespace = "${props.namespace}" - echo "=== Build Information ===" - echo "Service: smarketing-ai" - echo "Image Tag: ${imageTag}" - echo "Registry: ${props.registry}" - echo "Image Org: ${props.image_org}" - echo "Team ID: ${props.teamid}" + echo "Registry: ${props.registry}" + echo "Image Org: ${props.image_org}" + echo "Team ID: ${props.teamid}" + } + + stage("Check Changes") { + script { + def changes = sh( + script: "git diff --name-only HEAD~1 HEAD", + returnStdout: true + ).trim() + + echo "Changed files: ${changes}" + + if (!changes.contains("smarketing-ai/")) { + echo "No changes in smarketing-ai, skipping build" + currentBuild.result = 'SUCCESS' + error("Stopping pipeline - no changes detected") + } + + echo "Changes detected in smarketing-ai, proceeding with build" } + } - stage("Check Changes") { - script { - def changes = sh( - script: "git diff --name-only HEAD~1 HEAD", - returnStdout: true - ).trim() - - echo "Changed files: ${changes}" - - if (!changes.contains("smarketing-ai/")) { - echo "No changes in smarketing-ai, skipping build" - currentBuild.result = 'SUCCESS' - error("Stopping pipeline - no changes detected") - } - - echo "Changes detected in smarketing-ai, proceeding with build" + stage("Setup AKS") { + container('azure-cli') { + withCredentials([azureServicePrincipal('azure-credentials')]) { + sh """ + az login --service-principal -u \$AZURE_CLIENT_ID -p \$AZURE_CLIENT_SECRET -t \$AZURE_TENANT_ID + az aks get-credentials --resource-group rg-digitalgarage-02 --name aks-digitalgarage-02 --overwrite-existing + kubectl create namespace ${namespace} --dry-run=client -o yaml | kubectl apply -f - + """ } } + } - stage('Build & Push Docker Image') { - container('podman') { - sh 'podman system service -t 0 unix:///run/podman/podman.sock & sleep 2' + stage('Build & Push Docker Image') { + container('podman') { + sh 'podman system service -t 0 unix:///run/podman/podman.sock & sleep 2' - withCredentials([usernamePassword( - credentialsId: 'acr-credentials', - usernameVariable: 'ACR_USERNAME', - passwordVariable: 'ACR_PASSWORD' - )]) { - sh """ - echo "==========================================" - echo "Building smarketing-ai Python Flask application" - echo "Image Tag: ${imageTag}" - echo "==========================================" + withCredentials([usernamePassword( + credentialsId: 'acr-credentials', + usernameVariable: 'ACR_USERNAME', + passwordVariable: 'ACR_PASSWORD' + )]) { + sh """ + echo "==========================================" + echo "Building smarketing-ai Python Flask application" + echo "Image Tag: ${imageTag}" + echo "==========================================" - # ACR 로그인 - echo \$ACR_PASSWORD | podman login ${props.registry} --username \$ACR_USERNAME --password-stdin + # ACR 로그인 + echo \$ACR_PASSWORD | podman login ${props.registry} --username \$ACR_USERNAME --password-stdin - # Docker 이미지 빌드 - podman build \\ - -f smarketing-ai/deployment/Dockerfile \\ - -t ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} . + # Docker 이미지 빌드 + podman build \ + -f smarketing-ai/deployment/Dockerfile \ + -t ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} . - # 이미지 푸시 - podman push ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} + # 이미지 푸시 + podman push ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} - echo "Successfully built and pushed: ${props.registry}/${props.image_org}/smarketing-ai:${imageTag}" - """ - } + echo "Successfully built and pushed: ${props.registry}/${props.image_org}/smarketing-ai:${imageTag}" + """ } } + } - stage('Update Manifest Repository') { - container('git') { - script { - // Manifest Repository Clone - withCredentials([usernamePassword( - credentialsId: MANIFEST_CREDENTIAL_ID, - usernameVariable: 'GIT_USERNAME', - passwordVariable: 'GIT_PASSWORD' - )]) { - sh """ - echo "=== Git 설정 ===" - git config --global user.name "Jenkins CI" - git config --global user.email "jenkins@company.com" - - echo "=== Manifest Repository Clone ===" - rm -rf manifest-repo - git clone https://\$GIT_USERNAME:\$GIT_PASSWORD@github.com/won-ktds/smarketing-manifest.git manifest-repo - cd manifest-repo - """ - - def fullImageName = "${props.registry}/${props.image_org}/smarketing-ai:${imageTag}" - def deploymentFile = "smarketing-ai/deployments/smarketing-ai/smarketing-ai-deployment.yaml" - - sh """ - cd manifest-repo - - echo "=== smarketing-ai 이미지 태그 업데이트 ===" - if [ -f "${deploymentFile}" ]; then - # 이미지 태그 업데이트 (sed 사용) - sed -i 's|image: ${props.registry}/${props.image_org}/smarketing-ai:.*|image: ${fullImageName}|g' "${deploymentFile}" - echo "Updated ${deploymentFile} with new image: ${fullImageName}" - - # 변경사항 확인 - echo "=== 변경된 내용 확인 ===" - grep "image: ${props.registry}/${props.image_org}/smarketing-ai" "${deploymentFile}" || echo "이미지 태그 업데이트 확인 실패" - else - echo "Warning: ${deploymentFile} not found" - fi - """ - - sh """ - cd manifest-repo - - echo "=== Git 변경사항 확인 ===" - git status - git diff - - # 변경사항이 있으면 커밋 및 푸시 - if [ -n "\$(git status --porcelain)" ]; then - git add . - git commit -m "Update smarketing-ai to ${imageTag} - Build ${env.BUILD_NUMBER}" - git push origin main - echo "✅ Successfully updated manifest repository" - else - echo "ℹ️ No changes to commit" - fi - """ - } - } - } - } + stage('Generate & Apply Manifest') { + container('envsubst') { + withCredentials([ + string(credentialsId: 'SECRET_KEY', variable: 'SECRET_KEY'), + string(credentialsId: 'CLAUDE_API_KEY', variable: 'CLAUDE_API_KEY'), + string(credentialsId: 'OPENAI_API_KEY', variable: 'OPENAI_API_KEY'), + string(credentialsId: 'AZURE_STORAGE_ACCOUNT_NAME', variable: 'AZURE_STORAGE_ACCOUNT_NAME'), + string(credentialsId: 'AZURE_STORAGE_ACCOUNT_KEY', variable: 'AZURE_STORAGE_ACCOUNT_KEY') + ]) { + sh """ + export namespace=${namespace} + export replicas=${props.replicas} + export resources_requests_cpu=${props.resources_requests_cpu} + export resources_requests_memory=${props.resources_requests_memory} + export resources_limits_cpu=${props.resources_limits_cpu} + export resources_limits_memory=${props.resources_limits_memory} + export upload_folder=${props.upload_folder} + export max_content_length=${props.max_content_length} + export allowed_extensions=${props.allowed_extensions} + export server_host=${props.server_host} + export server_port=${props.server_port} + export azure_storage_container_name=${props.azure_storage_container_name} - stage('Trigger ArgoCD Sync') { - script { - echo """ -🎯 smarketing-ai CI Pipeline 완료! + # 이미지 경로 환경변수 설정 + export smarketing_image_path=${props.registry}/${props.image_org}/smarketing-ai:${imageTag} -📦 빌드된 이미지: -- ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} + # Sensitive 환경변수 설정 (Jenkins Credentials에서) + export secret_key=\$SECRET_KEY + export claude_api_key=\$CLAUDE_API_KEY + export openai_api_key=\$OPENAI_API_KEY + export azure_storage_account_name=\$AZURE_STORAGE_ACCOUNT_NAME + export azure_storage_account_key=\$AZURE_STORAGE_ACCOUNT_KEY -🔄 ArgoCD 동작: -- ArgoCD가 manifest repository 변경사항을 자동으로 감지합니다 -- smarketing-ai Application이 새로운 이미지로 동기화됩니다 -- ArgoCD UI에서 배포 상태를 모니터링하세요 - -🌐 ArgoCD UI: [ArgoCD 접속 URL] -📁 Manifest Repo: ${MANIFEST_REPO} + # manifest 생성 + envsubst < smarketing-ai/deployment/${manifest}.template > smarketing-ai/deployment/${manifest} + echo "Generated manifest file:" + cat smarketing-ai/deployment/${manifest} """ } } - // 성공 시 처리 - echo """ -✅ smarketing-ai CI Pipeline 성공! -🏷️ 새로운 이미지 태그: ${imageTag} -🔄 ArgoCD가 자동으로 배포를 시작합니다 - """ + container('azure-cli') { + sh """ + kubectl apply -f smarketing-ai/deployment/${manifest} - } catch (Exception e) { - // 실패 시 처리 - echo "❌ smarketing-ai CI Pipeline 실패: ${e.getMessage()}" - throw e - } finally { - // 정리 작업 (항상 실행) - container('podman') { - sh 'podman system prune -f || true' + echo "Waiting for smarketing deployment to be ready..." + kubectl -n ${namespace} wait --for=condition=available deployment/smarketing --timeout=300s + + echo "==========================================" + echo "Getting LoadBalancer External IP..." + + # External IP 확인 (최대 5분 대기) + for i in {1..30}; do + EXTERNAL_IP=\$(kubectl -n ${namespace} get service smarketing-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + if [ "\$EXTERNAL_IP" != "" ] && [ "\$EXTERNAL_IP" != "null" ]; then + echo "External IP assigned: \$EXTERNAL_IP" + break + fi + echo "Waiting for External IP... (attempt \$i/30)" + sleep 10 + done + + # 서비스 상태 확인 + kubectl -n ${namespace} get pods -l app=smarketing + kubectl -n ${namespace} get service smarketing-service + + echo "==========================================" + echo "Deployment Complete!" + echo "Service URL: http://\$EXTERNAL_IP:${props.server_port}" + echo "Health Check: http://\$EXTERNAL_IP:${props.server_port}/health" + echo "==========================================" + """ } - sh 'rm -rf manifest-repo || true' } } -} +} \ No newline at end of file diff --git a/smarketing-ai/deployment/Jenkinsfile_argo b/smarketing-ai/deployment/Jenkinsfile_argo new file mode 100644 index 0000000..8e07c93 --- /dev/null +++ b/smarketing-ai/deployment/Jenkinsfile_argo @@ -0,0 +1,196 @@ +// smarketing-backend/smarketing-ai/deployment/Jenkinsfile + +def PIPELINE_ID = "${env.BUILD_NUMBER}" + +def getImageTag() { + def dateFormat = new java.text.SimpleDateFormat('yyyyMMddHHmmss') + def currentDate = new Date() + return dateFormat.format(currentDate) +} + +podTemplate( + label: "${PIPELINE_ID}", + serviceAccount: 'jenkins', + containers: [ + containerTemplate(name: 'podman', image: "mgoltzsche/podman", ttyEnabled: true, command: 'cat', privileged: true), + containerTemplate(name: 'git', image: 'alpine/git:latest', command: 'cat', ttyEnabled: true) + ], + volumes: [ + emptyDirVolume(mountPath: '/run/podman', memory: false) + ] +) { + node(PIPELINE_ID) { + def props + def imageTag = getImageTag() + + // Manifest Repository 설정 + def MANIFEST_REPO = 'https://github.com/won-ktds/smarketing-manifest.git' + def MANIFEST_CREDENTIAL_ID = 'github-credentials-smarketing' + + try { + stage("Get Source") { + checkout scm + + // smarketing-ai 하위에 있는 설정 파일 읽기 + props = readProperties file: "smarketing-ai/deployment/deploy_env_vars" + + echo "=== Build Information ===" + echo "Service: smarketing-ai" + echo "Image Tag: ${imageTag}" + echo "Registry: ${props.registry}" + echo "Image Org: ${props.image_org}" + echo "Team ID: ${props.teamid}" + } + + stage("Check Changes") { + script { + def changes = sh( + script: "git diff --name-only HEAD~1 HEAD", + returnStdout: true + ).trim() + + echo "Changed files: ${changes}" + + if (!changes.contains("smarketing-ai/")) { + echo "No changes in smarketing-ai, skipping build" + currentBuild.result = 'SUCCESS' + error("Stopping pipeline - no changes detected") + } + + echo "Changes detected in smarketing-ai, proceeding with build" + } + } + + stage('Build & Push Docker Image') { + container('podman') { + sh 'podman system service -t 0 unix:///run/podman/podman.sock & sleep 2' + + withCredentials([usernamePassword( + credentialsId: 'acr-credentials', + usernameVariable: 'ACR_USERNAME', + passwordVariable: 'ACR_PASSWORD' + )]) { + sh """ + echo "==========================================" + echo "Building smarketing-ai Python Flask application" + echo "Image Tag: ${imageTag}" + echo "==========================================" + + # ACR 로그인 + echo \$ACR_PASSWORD | podman login ${props.registry} --username \$ACR_USERNAME --password-stdin + + # Docker 이미지 빌드 + podman build \\ + -f smarketing-ai/deployment/Dockerfile \\ + -t ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} . + + # 이미지 푸시 + podman push ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} + + echo "Successfully built and pushed: ${props.registry}/${props.image_org}/smarketing-ai:${imageTag}" + """ + } + } + } + + stage('Update Manifest Repository') { + container('git') { + script { + // Manifest Repository Clone + withCredentials([usernamePassword( + credentialsId: MANIFEST_CREDENTIAL_ID, + usernameVariable: 'GIT_USERNAME', + passwordVariable: 'GIT_PASSWORD' + )]) { + sh """ + echo "=== Git 설정 ===" + git config --global user.name "Jenkins CI" + git config --global user.email "jenkins@company.com" + + echo "=== Manifest Repository Clone ===" + rm -rf manifest-repo + git clone https://\$GIT_USERNAME:\$GIT_PASSWORD@github.com/won-ktds/smarketing-manifest.git manifest-repo + cd manifest-repo + """ + + def fullImageName = "${props.registry}/${props.image_org}/smarketing-ai:${imageTag}" + def deploymentFile = "smarketing-ai/deployments/smarketing-ai/smarketing-ai-deployment.yaml" + + sh """ + cd manifest-repo + + echo "=== smarketing-ai 이미지 태그 업데이트 ===" + if [ -f "${deploymentFile}" ]; then + # 이미지 태그 업데이트 (sed 사용) + sed -i 's|image: ${props.registry}/${props.image_org}/smarketing-ai:.*|image: ${fullImageName}|g' "${deploymentFile}" + echo "Updated ${deploymentFile} with new image: ${fullImageName}" + + # 변경사항 확인 + echo "=== 변경된 내용 확인 ===" + grep "image: ${props.registry}/${props.image_org}/smarketing-ai" "${deploymentFile}" || echo "이미지 태그 업데이트 확인 실패" + else + echo "Warning: ${deploymentFile} not found" + fi + """ + + sh """ + cd manifest-repo + + echo "=== Git 변경사항 확인 ===" + git status + git diff + + # 변경사항이 있으면 커밋 및 푸시 + if [ -n "\$(git status --porcelain)" ]; then + git add . + git commit -m "Update smarketing-ai to ${imageTag} - Build ${env.BUILD_NUMBER}" + git push origin main + echo "✅ Successfully updated manifest repository" + else + echo "ℹ️ No changes to commit" + fi + """ + } + } + } + } + + stage('Trigger ArgoCD Sync') { + script { + echo """ +🎯 smarketing-ai CI Pipeline 완료! + +📦 빌드된 이미지: +- ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} + +🔄 ArgoCD 동작: +- ArgoCD가 manifest repository 변경사항을 자동으로 감지합니다 +- smarketing-ai Application이 새로운 이미지로 동기화됩니다 +- ArgoCD UI에서 배포 상태를 모니터링하세요 + +🌐 ArgoCD UI: [ArgoCD 접속 URL] +📁 Manifest Repo: ${MANIFEST_REPO} + """ + } + } + + // 성공 시 처리 + echo """ +✅ smarketing-ai CI Pipeline 성공! +🏷️ 새로운 이미지 태그: ${imageTag} +🔄 ArgoCD가 자동으로 배포를 시작합니다 + """ + + } catch (Exception e) { + // 실패 시 처리 + echo "❌ smarketing-ai CI Pipeline 실패: ${e.getMessage()}" + throw e + } finally { + // 정리 작업 (항상 실행) + container('podman') { + sh 'podman system prune -f || true' + } + sh 'rm -rf manifest-repo || true' + } + } +} diff --git a/smarketing-ai/deployment/Jenkinsfile_backup b/smarketing-ai/deployment/Jenkinsfile_backup deleted file mode 100644 index e55f855..0000000 --- a/smarketing-ai/deployment/Jenkinsfile_backup +++ /dev/null @@ -1,176 +0,0 @@ -def PIPELINE_ID = "${env.BUILD_NUMBER}" - -def getImageTag() { - def dateFormat = new java.text.SimpleDateFormat('yyyyMMddHHmmss') - def currentDate = new Date() - return dateFormat.format(currentDate) -} - -podTemplate( - label: "${PIPELINE_ID}", - serviceAccount: 'jenkins', - containers: [ - containerTemplate(name: 'podman', image: "mgoltzsche/podman", ttyEnabled: true, command: 'cat', privileged: true), - containerTemplate(name: 'azure-cli', image: 'hiondal/azure-kubectl:latest', command: 'cat', ttyEnabled: true), - containerTemplate(name: 'envsubst', image: "hiondal/envsubst", command: 'sleep', args: '1h') - ], - volumes: [ - emptyDirVolume(mountPath: '/run/podman', memory: false), - emptyDirVolume(mountPath: '/root/.azure', memory: false) - ] -) { - node(PIPELINE_ID) { - def props - def imageTag = getImageTag() - def manifest = "deploy.yaml" - def namespace - - stage("Get Source") { - checkout scm - props = readProperties file: "smarketing-ai/deployment/deploy_env_vars" - namespace = "${props.namespace}" - - echo "Registry: ${props.registry}" - echo "Image Org: ${props.image_org}" - echo "Team ID: ${props.teamid}" - } - - stage("Check Changes") { - script { - def changes = sh( - script: "git diff --name-only HEAD~1 HEAD", - returnStdout: true - ).trim() - - echo "Changed files: ${changes}" - - if (!changes.contains("smarketing-ai/")) { - echo "No changes in smarketing-ai, skipping build" - currentBuild.result = 'SUCCESS' - error("Stopping pipeline - no changes detected") - } - - echo "Changes detected in smarketing-ai, proceeding with build" - } - } - - stage("Setup AKS") { - container('azure-cli') { - withCredentials([azureServicePrincipal('azure-credentials')]) { - sh """ - az login --service-principal -u \$AZURE_CLIENT_ID -p \$AZURE_CLIENT_SECRET -t \$AZURE_TENANT_ID - az aks get-credentials --resource-group rg-digitalgarage-02 --name aks-digitalgarage-02 --overwrite-existing - kubectl create namespace ${namespace} --dry-run=client -o yaml | kubectl apply -f - - """ - } - } - } - - stage('Build & Push Docker Image') { - container('podman') { - sh 'podman system service -t 0 unix:///run/podman/podman.sock & sleep 2' - - withCredentials([usernamePassword( - credentialsId: 'acr-credentials', - usernameVariable: 'ACR_USERNAME', - passwordVariable: 'ACR_PASSWORD' - )]) { - sh """ - echo "==========================================" - echo "Building smarketing-ai Python Flask application" - echo "Image Tag: ${imageTag}" - echo "==========================================" - - # ACR 로그인 - echo \$ACR_PASSWORD | podman login ${props.registry} --username \$ACR_USERNAME --password-stdin - - # Docker 이미지 빌드 - podman build \ - -f smarketing-ai/deployment/Dockerfile \ - -t ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} . - - # 이미지 푸시 - podman push ${props.registry}/${props.image_org}/smarketing-ai:${imageTag} - - echo "Successfully built and pushed: ${props.registry}/${props.image_org}/smarketing-ai:${imageTag}" - """ - } - } - } - - stage('Generate & Apply Manifest') { - container('envsubst') { - withCredentials([ - string(credentialsId: 'SECRET_KEY', variable: 'SECRET_KEY'), - string(credentialsId: 'CLAUDE_API_KEY', variable: 'CLAUDE_API_KEY'), - string(credentialsId: 'OPENAI_API_KEY', variable: 'OPENAI_API_KEY'), - string(credentialsId: 'AZURE_STORAGE_ACCOUNT_NAME', variable: 'AZURE_STORAGE_ACCOUNT_NAME'), - string(credentialsId: 'AZURE_STORAGE_ACCOUNT_KEY', variable: 'AZURE_STORAGE_ACCOUNT_KEY') - ]) { - sh """ - export namespace=${namespace} - export replicas=${props.replicas} - export resources_requests_cpu=${props.resources_requests_cpu} - export resources_requests_memory=${props.resources_requests_memory} - export resources_limits_cpu=${props.resources_limits_cpu} - export resources_limits_memory=${props.resources_limits_memory} - export upload_folder=${props.upload_folder} - export max_content_length=${props.max_content_length} - export allowed_extensions=${props.allowed_extensions} - export server_host=${props.server_host} - export server_port=${props.server_port} - export azure_storage_container_name=${props.azure_storage_container_name} - - # 이미지 경로 환경변수 설정 - export smarketing_image_path=${props.registry}/${props.image_org}/smarketing-ai:${imageTag} - - # Sensitive 환경변수 설정 (Jenkins Credentials에서) - export secret_key=\$SECRET_KEY - export claude_api_key=\$CLAUDE_API_KEY - export openai_api_key=\$OPENAI_API_KEY - export azure_storage_account_name=\$AZURE_STORAGE_ACCOUNT_NAME - export azure_storage_account_key=\$AZURE_STORAGE_ACCOUNT_KEY - - # manifest 생성 - envsubst < smarketing-ai/deployment/${manifest}.template > smarketing-ai/deployment/${manifest} - echo "Generated manifest file:" - cat smarketing-ai/deployment/${manifest} - """ - } - } - - container('azure-cli') { - sh """ - kubectl apply -f smarketing-ai/deployment/${manifest} - - echo "Waiting for smarketing deployment to be ready..." - kubectl -n ${namespace} wait --for=condition=available deployment/smarketing --timeout=300s - - echo "==========================================" - echo "Getting LoadBalancer External IP..." - - # External IP 확인 (최대 5분 대기) - for i in {1..30}; do - EXTERNAL_IP=\$(kubectl -n ${namespace} get service smarketing-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - if [ "\$EXTERNAL_IP" != "" ] && [ "\$EXTERNAL_IP" != "null" ]; then - echo "External IP assigned: \$EXTERNAL_IP" - break - fi - echo "Waiting for External IP... (attempt \$i/30)" - sleep 10 - done - - # 서비스 상태 확인 - kubectl -n ${namespace} get pods -l app=smarketing - kubectl -n ${namespace} get service smarketing-service - - echo "==========================================" - echo "Deployment Complete!" - echo "Service URL: http://\$EXTERNAL_IP:${props.server_port}" - echo "Health Check: http://\$EXTERNAL_IP:${props.server_port}/health" - echo "==========================================" - """ - } - } - } -} \ No newline at end of file diff --git a/smarketing-ai/deployment/deploy.yaml.template_backup b/smarketing-ai/deployment/deploy.yaml.template similarity index 100% rename from smarketing-ai/deployment/deploy.yaml.template_backup rename to smarketing-ai/deployment/deploy.yaml.template diff --git a/smarketing-ai/uploads/temp/temp_1de3d733-f3bb-44cf-8b4d-3d1e7c31cc42.jpg b/smarketing-ai/uploads/temp/temp_1de3d733-f3bb-44cf-8b4d-3d1e7c31cc42.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_1de3d733-f3bb-44cf-8b4d-3d1e7c31cc42.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_272b6c7e-161f-4977-b91a-185f85b0a6cf.jpg b/smarketing-ai/uploads/temp/temp_272b6c7e-161f-4977-b91a-185f85b0a6cf.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_272b6c7e-161f-4977-b91a-185f85b0a6cf.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_3c2f489c-9a96-48e2-b180-ff13caaee373.jpg b/smarketing-ai/uploads/temp/temp_3c2f489c-9a96-48e2-b180-ff13caaee373.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_3c2f489c-9a96-48e2-b180-ff13caaee373.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_4815be20-a36b-41f2-bcc8-50bf82f23bd1.jpg b/smarketing-ai/uploads/temp/temp_4815be20-a36b-41f2-bcc8-50bf82f23bd1.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_4815be20-a36b-41f2-bcc8-50bf82f23bd1.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_5a50b9d5-7ae8-4410-bf76-3f114020ff87.jpg b/smarketing-ai/uploads/temp/temp_5a50b9d5-7ae8-4410-bf76-3f114020ff87.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_5a50b9d5-7ae8-4410-bf76-3f114020ff87.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_60ad2f5c-8dd3-46b4-bd4b-5cc54b28a2fa.jpg b/smarketing-ai/uploads/temp/temp_60ad2f5c-8dd3-46b4-bd4b-5cc54b28a2fa.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_60ad2f5c-8dd3-46b4-bd4b-5cc54b28a2fa.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_893f4988-2fe7-4c34-a0f5-bf3f8c1f35fa.jpg b/smarketing-ai/uploads/temp/temp_893f4988-2fe7-4c34-a0f5-bf3f8c1f35fa.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_893f4988-2fe7-4c34-a0f5-bf3f8c1f35fa.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_997c1ddc-b000-46ac-9393-c077c9ee3d41.jpg b/smarketing-ai/uploads/temp/temp_997c1ddc-b000-46ac-9393-c077c9ee3d41.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_997c1ddc-b000-46ac-9393-c077c9ee3d41.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_9fd7f543-96bf-4c0d-a9eb-7092e733a4ba.jpg b/smarketing-ai/uploads/temp/temp_9fd7f543-96bf-4c0d-a9eb-7092e733a4ba.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_9fd7f543-96bf-4c0d-a9eb-7092e733a4ba.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_d126c548-36c7-4a51-8962-01f1d9b70480.jpg b/smarketing-ai/uploads/temp/temp_d126c548-36c7-4a51-8962-01f1d9b70480.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_d126c548-36c7-4a51-8962-01f1d9b70480.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_e42a6e2a-cac7-4400-aa90-11c1651ca5fb.jpg b/smarketing-ai/uploads/temp/temp_e42a6e2a-cac7-4400-aa90-11c1651ca5fb.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_e42a6e2a-cac7-4400-aa90-11c1651ca5fb.jpg and /dev/null differ diff --git a/smarketing-ai/uploads/temp/temp_e63e2a7d-bf42-4c2c-9bcb-609578b6f8b7.jpg b/smarketing-ai/uploads/temp/temp_e63e2a7d-bf42-4c2c-9bcb-609578b6f8b7.jpg deleted file mode 100644 index 628c52a..0000000 Binary files a/smarketing-ai/uploads/temp/temp_e63e2a7d-bf42-4c2c-9bcb-609578b6f8b7.jpg and /dev/null differ