myLogger = \Config\Services::mylogger(); } // public function fedeploy() // { // $request = $this->request; // // Multiple zip files: // // $zipFiles = $this->request->getFileMultiple('zip_files'); // $zipFiles = $this->request->getFile('zip_files');//('zip_files'); // // print_r($zipFiles);die(); // // Matching dropdown/text values (arrays, indexed same as zip_files[]) // $zipFolders = (array) $request->getPost('zip_folder'); // e.g. ["web/", "dist/"] // $s3Buckets = (array) $request->getPost('s3_bucket'); // e.g. ["benefits-app-bucket", ...] // $s3Prefixes = (array) $request->getPost('s3_prefix'); // e.g. ["hr/", "payroll/"] // $cfDistributions = (array) $request->getPost('cf_distribution_id'); // e.g. ["DIST1", "DIST1", "DIST2"] // $cfPathsList = (array) $request->getPost('cf_paths'); // e.g. ["/hr/*", "/hr/special/*", "/payroll/*"] // // Path to Python interpreter and deploy_assets.py script // $pythonBin = getenv('PY_PATH'); // adjust if needed // $scriptPath = getenv('PY_SCRIPT_PATH'); // full path to your script // $results = []; // if (empty($zipFiles)) { // return $this->response->setJSON([ // 'status' => 'error', // 'message' => 'No zip files uploaded', // ]); // } // // -------------------------------------------------------- // // 1) Pre-process distribution IDs → group by distribution // // - So we can run ONE invalidation per distribution // // - And merge all paths into a single JSON array // // -------------------------------------------------------- // $distGroups = []; // [distId => ['indexes' => [...], 'paths' => [...], 'firstIndex' => int]] // foreach ($cfDistributions as $i => $distId) { // $distId = trim((string) $distId); // $path = trim((string) ($cfPathsList[$i] ?? '')); // // Only consider entries where both distribution ID and path are set // if ($distId === '' || $path === '') { // continue; // } // if (!isset($distGroups[$distId])) { // $distGroups[$distId] = [ // 'indexes' => [], // 'paths' => [], // ]; // } // $distGroups[$distId]['indexes'][] = $i; // $distGroups[$distId]['paths'][] = $path; // } // // Set firstIndex and unique paths per distribution // foreach ($distGroups as $distId => $info) { // $distGroups[$distId]['firstIndex'] = $info['indexes'][0]; // first file index for this dist // $distGroups[$distId]['paths'] = array_values(array_unique($info['paths'])); // unique paths // } // // -------------------------------------------------------- // // 2) Process each uploaded file // // -------------------------------------------------------- // foreach ($zipFiles as $index => $file) { // if (!$file->isValid() || $file->hasMoved()) { // $results[] = [ // 'file' => $file->getName(), // 'status' => 'error', // 'message' => 'Invalid file or already moved.', // ]; // continue; // } // // Read matching form values (or fallback) // $zipFolder = $zipFolders[$index] ?? 'web/'; // default example // $s3Bucket = $s3Buckets[$index] ?? ''; // $s3Prefix = $s3Prefixes[$index] ?? ''; // $cfDistribution = $cfDistributions[$index] ?? ''; // $cfDistribution = trim((string) $cfDistribution); // // Move file into a known directory (keep original name) // // $uploadDir = WRITEPATH . 'uploads/deploy'; // $uploadDir = '/home/ubuntu/py'; // if (!is_dir($uploadDir)) { // mkdir($uploadDir, 0775, true); // } // $originalName = $file->getName(); // $file->move($uploadDir, $originalName); // $zipPath = $uploadDir . DIRECTORY_SEPARATOR . $originalName; // // -------------------------------------------------------- // // Decide whether THIS file should trigger invalidation // // - Only firstIndex of each distribution will do it // // - cf-paths-json = JSON array of all unique paths for that dist // // -------------------------------------------------------- // $doInvalidation = false; // $cfPathsJson = ''; // if ($cfDistribution !== '' && isset($distGroups[$cfDistribution])) { // $group = $distGroups[$cfDistribution]; // if ($group['firstIndex'] === $index) { // // This is the first file for this distribution ID → do invalidation ONCE // $doInvalidation = true; // // Build CloudFront paths JSON array (AWS syntax: ["path1", "path2", ...]) // $cfPathsJson = json_encode($group['paths']); // e.g. ["\/hr\/*","\/hr\/special\/*"] // } // // Else: same distribution ID but NOT first index → no invalidation // } // // -------------------------------------------------------- // // Build the python command safely using escapeshellarg // // -------------------------------------------------------- // $cmdParts = [ // escapeshellarg($pythonBin), // escapeshellarg($scriptPath), // '--zip-path', escapeshellarg($zipPath), // '--zip-folder', escapeshellarg($zipFolder), // '--s3-bucket', escapeshellarg($s3Bucket), // '--s3-prefix', escapeshellarg($s3Prefix), // '--do-webhook', // always send webhook after success // ]; // if ($doInvalidation) { // $cmdParts[] = '--do-invalidation'; // $cmdParts[] = '--cf-distribution-id'; // $cmdParts[] = escapeshellarg($cfDistribution); // $cmdParts[] = '--cf-paths-json'; // $cmdParts[] = escapeshellarg($cfPathsJson); // e.g. '["/hr/*","/hr/special/*"]' // } // // Final command string (2>&1 to capture stderr too) // $cmd = implode(' ', $cmdParts) . ' 2>&1'; // print_r($cmd);die(); // $output = []; // $returnVar = 0; // exec($cmd, $output, $returnVar); // $results[] = [ // 'file' => $originalName, // 'zip_path' => $zipPath, // 'command' => $cmd, // 'output' => $output, // 'exit_code' => $returnVar, // 'status' => $returnVar === 0 ? 'success' : 'error', // ]; // } // return $this->response->setJSON([ // 'status' => 'completed', // 'results' => $results, // ]); // } public function fedeploy() { $request = $this->request; echo 'HI';die(); // Single zip file: $file = $request->getFile('zip_file'); if (!$file || !$file->isValid()) { return $this->response->setJSON([ 'status' => 'error', 'message' => 'No valid zip file uploaded', ]); } echo 'cool';die(); // Read scalar form values $zipFolder = (string) $request->getPost('zip_folder') ?: 'web/'; $s3Bucket = (string) $request->getPost('s3_bucket') ?: ''; $s3Prefix = (string) $request->getPost('s3_prefix') ?: ''; $cfDistribution = trim((string) $request->getPost('cf_distribution_id')); $cfPathsRaw = (string) $request->getPost('cf_paths'); // Python interpreter and script path from env $pythonBin = getenv('PY_PATH'); // e.g. /usr/bin/python3 $scriptPath = getenv('PY_SCRIPT_PATH'); // e.g. /home/ubuntu/deploy_assets.py if (empty($pythonBin) || empty($scriptPath)) { return $this->response->setJSON([ 'status' => 'error', 'message' => 'Python path or script path not configured in environment.', ]); } // Move file into known directory (keep original name) $uploadDir = '~/py'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0775, true); } $originalName = $file->getName(); $file->move($uploadDir, $originalName); $zipPath = $uploadDir . DIRECTORY_SEPARATOR . $originalName; // ----------------------------- // CloudFront invalidation data // ----------------------------- $doInvalidation = false; $cfPathsJson = ''; // Allow comma or newline separated paths: "/hr/*,/hr/special/*" or // "/hr/*\n/hr/special/*" $paths = array_filter( array_map('trim', preg_split('/[\r\n,]+/', $cfPathsRaw)), 'strlen' ); if ($cfDistribution !== '' && !empty($paths)) { $doInvalidation = true; $cfPathsJson = json_encode($paths); // e.g. ["\/hr\/*","\/hr\/special\/*"] } // ----------------------------- // Build python command // ----------------------------- $cmdParts = [ escapeshellarg($pythonBin), escapeshellarg($scriptPath), '--zip-path', escapeshellarg($zipPath), '--zip-folder', escapeshellarg($zipFolder), '--s3-bucket', escapeshellarg($s3Bucket), '--s3-prefix', escapeshellarg($s3Prefix), '--do-webhook', // always send webhook after success ]; if ($doInvalidation) { $cmdParts[] = '--do-invalidation'; $cmdParts[] = '--cf-distribution-id'; $cmdParts[] = escapeshellarg($cfDistribution); $cmdParts[] = '--cf-paths-json'; $cmdParts[] = escapeshellarg($cfPathsJson); } // Final command string (2>&1 to capture stderr too) $cmd = implode(' ', $cmdParts) . ' 2>&1'; $output = []; $returnVar = 0; print_r($cmd);die(); exec($cmd, $output, $returnVar); $result = [ 'file' => $originalName, 'zip_path' => $zipPath, 'command' => $cmd, 'output' => $output, 'exit_code' => $returnVar, 'status' => $returnVar === 0 ? 'success' : 'error', ]; return $this->response->setJSON([ 'status' => 'completed', 'result' => $result, ]); } public function fedeploy_view() { // $this->load->view('fedeploy'); $this->loadLayout('fedeploy'); } public function fetest() { echo 'Hello from DeployController fetest!'; } }