-
-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
deploy error: accepts at most 1 arg(s), received 3 - docker login ? #538
Comments
@hervejegou Strange. I have not made any changes to the deployment process in a long time. Maybe this issue is caused by an update to If doing it manually, there are two ways to deploy: 1. Deploy the source code in an
|
} else if (command === 'deploy' || command === 'deploy-update') { | |
let dockerImageName, dockerDefaultImageName; | |
let dockerDefaultImageVersionTag = 'v1.0.0'; | |
let nextVersionTag; | |
let appPath = arg1 || '.'; | |
let absoluteAppPath = path.resolve(appPath); | |
let pkg = parsePackageFile(appPath); | |
let appName = pkg.name; | |
let isUpdate = (command === 'deploy-update'); | |
let targetCPUUtilization = 50; | |
let maxPodsPerService = 10; | |
let failedToDeploy = function (err) { | |
errorMessage(`Failed to deploy the '${appName}' app. ${err.message}`); | |
process.exit(); | |
}; | |
let socketClusterK8sConfigFilePath = appPath + '/socketcluster-k8s.json'; | |
let socketClusterK8sConfig = parseJSONFile(socketClusterK8sConfigFilePath); | |
let addAuthDetailsToSocketClusterK8s = function (socketClusterK8sConfigJSON, username, password) { | |
if (!socketClusterK8sConfigJSON.docker) { | |
socketClusterK8sConfigJSON.docker = {}; | |
} | |
socketClusterK8sConfigJSON.docker.auth = Buffer.from(`${username}:${password}`, 'utf8').toString('base64'); | |
}; | |
let saveSocketClusterK8sConfigFile = function (socketClusterK8sConfigJSON) { | |
fs.writeFileSync(socketClusterK8sConfigFilePath, JSON.stringify(socketClusterK8sConfigJSON, null, 2)); | |
}; | |
let parseVersionTag = function (fullImageName) { | |
let matches = fullImageName.match(/:[^:]*$/); | |
if (!matches) { | |
return ''; | |
} | |
return matches[0] || ''; | |
}; | |
let setImageVersionTag = function (imageName, versionTag) { | |
if (versionTag.indexOf(':') !== 0) { | |
versionTag = ':' + versionTag; | |
} | |
return imageName.replace(/(\/[^\/:]*)(:[^:]*)?$/g, `$1${versionTag}`); | |
}; | |
let promptDockerAuthDetails = function (callback) { | |
let handleSaveDockerAuthDetails = function (saveAuthDetails) { | |
saveDockerAuthDetails = saveAuthDetails; | |
callback(dockerUsername, dockerPassword, saveDockerAuthDetails); | |
}; | |
let promptSaveAuthDetails = function () { | |
promptConfirm(`Would you like to save your Docker registry username and password as Base64 to ${socketClusterK8sConfigFilePath}?`, {default: true}, handleSaveDockerAuthDetails); | |
}; | |
let handlePassword = function (password) { | |
dockerPassword = password; | |
if (saveDockerAuthDetails != null) { | |
handleSaveDockerAuthDetails(saveDockerAuthDetails); | |
return; | |
} | |
promptSaveAuthDetails(); | |
}; | |
let handleUsername = function (username) { | |
dockerUsername = username; | |
if (dockerPassword != null) { | |
handlePassword(dockerPassword); | |
return; | |
} | |
promptInput('Enter your Docker registry password:', handlePassword, true); | |
}; | |
let promptUsername = function () { | |
if (dockerUsername != null) { | |
handleUsername(dockerUsername); | |
return; | |
} | |
promptInput('Enter your Docker registry username:', handleUsername); | |
}; | |
promptUsername(); | |
}; | |
let performDeployment = function (dockerConfig, versionTag, username, password) { | |
let dockerLoginCommand = `docker login -u "${username}" -p "${password}"`; | |
let fullVersionTag; | |
if (versionTag) { | |
fullVersionTag = `:${versionTag}`; | |
} else { | |
fullVersionTag = parseVersionTag(dockerConfig.imageName); | |
} | |
dockerConfig.imageName = setImageVersionTag(dockerConfig.imageName, fullVersionTag); | |
if (saveDockerAuthDetails) { | |
addAuthDetailsToSocketClusterK8s(socketClusterK8sConfig, username, password); | |
} | |
try { | |
saveSocketClusterK8sConfigFile(socketClusterK8sConfig); | |
execSync(`docker build -t ${dockerConfig.imageName} .`, {stdio: 'inherit'}); | |
execSync(`${dockerLoginCommand}; docker push ${dockerConfig.imageName}`, {stdio: 'inherit'}); | |
if (tlsSecretName && tlsKeyPath && tlsCertPath) { | |
uploadTLSSecret(tlsSecretName, tlsKeyPath, tlsCertPath, warningMessage); | |
} | |
let kubernetesDirPath = appPath + '/kubernetes'; | |
let kubeConfSCCWorker = getSCCWorkerDeploymentDefPath(kubernetesDirPath); | |
let kubeConfContentSCCWorker = fs.readFileSync(kubeConfSCCWorker, {encoding: 'utf8'}); | |
let deploymentConfSCCWorker = YAML.parse(kubeConfContentSCCWorker); | |
let initContainersSCCWorker = deploymentConfSCCWorker.spec.template.spec.initContainers; | |
initContainersSCCWorker.forEach((value, index) => { | |
if (value) { | |
if (value.name === 'app-src-container') { | |
initContainersSCCWorker[index].image = dockerConfig.imageName; | |
} | |
} | |
}); | |
let formattedYAMLStringSCCWorker = sanitizeYAML(YAML.stringify(deploymentConfSCCWorker, Infinity, 2)); | |
fs.writeFileSync(kubeConfSCCWorker, formattedYAMLStringSCCWorker); | |
let kubeConfSCCBroker = getSCCBrokerDeploymentDefPath(kubernetesDirPath); | |
let kubeConfContentSCCBroker = fs.readFileSync(kubeConfSCCBroker, {encoding: 'utf8'}); | |
let deploymentConfSCCBroker = YAML.parse(kubeConfContentSCCBroker); | |
let formattedYAMLStringSCCBroker = sanitizeYAML(YAML.stringify(deploymentConfSCCBroker, Infinity, 2)); | |
fs.writeFileSync(kubeConfSCCBroker, formattedYAMLStringSCCBroker); | |
let ingressKubeFileName = 'scc-ingress.yaml'; | |
let sccWorkerDeploymentFileName = 'scc-worker-deployment.yaml'; | |
let deploySuccess = () => { | |
successMessage( | |
`The '${appName}' app was deployed successfully - You should be able to access it online ` + | |
`once it has finished booting up. This can take a while depending on your platform.` | |
); | |
process.exit(); | |
}; | |
if (isUpdate) { | |
try { | |
execSync(`kubectl replace -f ${kubernetesDirPath}/${sccWorkerDeploymentFileName}`, {stdio: 'inherit'}); | |
} catch (err) {} | |
deploySuccess(); | |
} else { | |
let kubeFiles = fs.readdirSync(kubernetesDirPath); | |
let serviceAndDeploymentKubeFiles = kubeFiles.filter((configFilePath) => { | |
return configFilePath != ingressKubeFileName; | |
}); | |
serviceAndDeploymentKubeFiles.forEach((configFilePath) => { | |
let absolutePath = path.resolve(kubernetesDirPath, configFilePath); | |
execSync(`kubectl create -f ${absolutePath}`, {stdio: 'inherit'}); | |
}); | |
// Wait a few seconds before deploying ingress (due to a bug in some environments). | |
setTimeout(() => { | |
try { | |
execSync(`kubectl create -f ${kubernetesDirPath}/${ingressKubeFileName}`, {stdio: 'inherit'}); | |
deploySuccess(); | |
} catch (err) { | |
failedToDeploy(err); | |
} | |
}, 7000); | |
} | |
} catch (err) { | |
failedToDeploy(err); | |
} | |
}; | |
let handleDockerVersionTagAndPushToDockerImageRepo = function (versionTag) { | |
socketClusterK8sConfig.docker.imageName = setImageVersionTag(socketClusterK8sConfig.docker.imageName, nextVersionTag); | |
let dockerConfig = socketClusterK8sConfig.docker; | |
if (dockerConfig.auth) { | |
let authParts = Buffer.from(dockerConfig.auth, 'base64').toString('utf8').split(':'); | |
dockerUsername = authParts[0]; | |
dockerPassword = authParts[1]; | |
performDeployment(dockerConfig, versionTag, dockerUsername, dockerPassword); | |
} else { | |
promptDockerAuthDetails((username, password) => { | |
performDeployment(dockerConfig, versionTag, username, password); | |
}); | |
} | |
}; | |
let incrementVersion = function (versionString) { | |
return versionString.replace(/[^.]$/, (match) => { | |
return parseInt(match) + 1; | |
}); | |
}; | |
let pushToDockerImageRepo = function () { | |
let versionTagString = parseVersionTag(socketClusterK8sConfig.docker.imageName).replace(/^:/, ''); | |
if (versionTagString) { | |
if (isUpdate) { | |
nextVersionTag = incrementVersion(versionTagString); | |
} else { | |
nextVersionTag = versionTagString; | |
} | |
} else { | |
nextVersionTag = dockerDefaultImageVersionTag; | |
} | |
promptInput(`Enter the Docker version tag for this deployment (Default: ${nextVersionTag}):`, handleDockerVersionTagAndPushToDockerImageRepo); | |
}; | |
if (socketClusterK8sConfig.docker && socketClusterK8sConfig.docker.imageRepo) { | |
pushToDockerImageRepo(); | |
} else { | |
let saveSocketClusterK8sConfigs = function () { | |
socketClusterK8sConfig.docker = { | |
imageRepo: 'https://index.docker.io/v1/', | |
imageName: dockerImageName | |
}; | |
if (saveDockerAuthDetails) { | |
addAuthDetailsToSocketClusterK8s(socketClusterK8sConfig, dockerUsername, dockerPassword); | |
} | |
try { | |
saveSocketClusterK8sConfigFile(socketClusterK8sConfig); | |
} catch (err) { | |
failedToDeploy(err); | |
} | |
pushToDockerImageRepo(); | |
}; | |
let handleDockerImageName = function (imageName) { | |
imageName = imageName || dockerDefaultImageName; | |
let slashes = imageName.match(/\//g) || []; | |
if (slashes.length !== 1) { | |
failedToDeploy( | |
new Error('Invalid Docker image name; it must be in the format organizationName/projectName') | |
); | |
} | |
dockerImageName = setImageVersionTag(imageName, dockerDefaultImageVersionTag); | |
saveSocketClusterK8sConfigs(); | |
}; | |
let promptDockerImageName = function () { | |
dockerDefaultImageName = `${dockerUsername}/${appName}`; | |
promptInput(`Enter the Docker image name without the version tag (Or press enter for default: ${dockerDefaultImageName}):`, handleDockerImageName); | |
}; | |
promptK8sTLSCredentials(() => { | |
promptDockerAuthDetails(promptDockerImageName); | |
}); | |
} |
deploy
. It's not very complex but the logic here looks messy because it was written a long time ago before async/await (you kind of have to read the code backwards to follow the callbacks ;p).
2. Build a custom scc-worker from scratch with your source code built in
It will still work the same way architecturally but in this case it takes more space since the entire Node.js environment is inside the container (not just your source code) and it has to be entirely rebuilt and pushed even if you do a 1-line change.
That said this should be a lot easier to do manually.
In this case, you can simply customize scc-worker-deployment.yaml
to point to your container image and make sure that you use the same environment variables so that your containers will be exposed correctly to the cluster.
I have the same issue. I am running on windows. If i paste the command in powershell it will run. |
seems like this fix to the cli.js seems to work. basically splitting up the login and push.
|
@jondubois We have moved to a deployment using GitHub actions. So every PR triggers a test image build and if it passes, the PR can be merged and on merge (or on any direct commit) we have a GitHub action that deploys the update to our K8 cluster. |
@hervejegou Glad you found a solution. A guide would be great. If you share the link with me, I can add it to the socketcluster.io website. We have a pending PR which should address the issue with the CLI. I just haven't had the time to test it yet. |
Hi Jonathan:
When deploying with s
socketcluster deploy
I get an error after image is built. it fails at 'docker login' apparently:If I run the
docker login
command by itself, it succeeds (with a warning:PROBLEM:
I never had this issue before (we have used socketcluster for last one year - works great by the way !) and I searched online and do not seem to find where this come from.
Also I am able to run these 2 commands manually:
ALTERNATIVE FIX:
Would you have the list of commands to perform 'socketcluster deploy' manually so that I can perform the initial deploy manually and hopefully the 'socketcluster update' will work ?
The text was updated successfully, but these errors were encountered: