Skip to content
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

Ghost install thinks it’s running in a non interactive shell #1788

Closed
danielraffel opened this issue Sep 17, 2023 · 6 comments
Closed

Ghost install thinks it’s running in a non interactive shell #1788

danielraffel opened this issue Sep 17, 2023 · 6 comments
Labels

Comments

@danielraffel
Copy link

Welcome to Ghost-CLI's GitHub repo! 👋🎉

Do you need help or have a question? Please come chat in our forum: https://forum.ghost.org 👫.

Docs: https://ghost.org/docs/ 📖.

Please be aware that the team behind the Ghost CLI only supports the recommended stack: https://github.com/TryGhost/Ghost-cli#recommended-stack.

Summary

I am trying to run ghost install from a script, that’s running in an interactive SSH shell, running on a VM in interactive mode.

Local machine

  • runs local.sh script
  • which "ssh -i -t" to the VM
  • downloads remote.sh script from github
  • triggers remote.sh script to execute on VM using a service-account with sudo access that prepares machine and installs ghost

VM

  • executes remote.sh but has issues when it gets to Ghost install

It appears that Ghost install (eg the CLI) thinks it’s running in a non interactive shell the way I am using it. Perhaps there's something the CLI could enable to support this use case? I have tried forcing pseudo emulation mode with -tt but that hasn't worked either.

Steps to Reproduce

Some background context: I am trying to make it easy for others to install Ghost on a free-tier Google micro-instance and have started this project which is very close to working:

I run the setup script (sh gcloud_ghost_instancer.sh) on my local machine. It does a bunch of stuff to create and setup the google VM. Once the VM is created it 1) the script SSH’s in to the VM using a service-account with sudo access via an interactive shell 2) downloads another script on to the VM 3) runs the downloaded script to prepare the machine for, and install, Ghost:

ssh -t -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -i $HOME/.ssh/service_account_key-${INSTANCE_NAME} service-account@$INSTANCE_IP <<'ENDSSH'

        # Download the installer script from GitHub
        curl -O https://raw.githubusercontent.com/danielraffel/gcloud_ghost_instancer/main/install_on_server.sh

        # Make it executable and run it
        chmod +x install_on_server.sh
        sh ./install_on_server.sh
ENDSSH

The script running on the server (install_on_server.sh) is running inside the SSH shell. As alluded to in my original comment, I had started writing this script by passing variables to the ghost installer (minus the URL) hoping it would trigger just that part of the installer for a user to configure (and automate the rest). But, when I had a long string of parameters, I kept getting an error about not passing --URL. Then, when I removed all parameters and just ran Ghost Install I started getting errors that the “content folder is not owned by the current user ghost install” This is confusing since you see below the folders are setup correctly. However, this is is running inside a shell, on a VM, by a service-account with sudo access. These are the parts of the script which seem to not be working correctly.

# Install Ghost CLI
sudo npm install ghost-cli@latest -g

#Make a new directory called ghost, set its permissions, then navigate to it:
sudo mkdir -p /var/www/ghost
sudo chown service-account:service-account /var/www/ghost
sudo chmod 775 /var/www/ghost

# Navigate to the website folder and install Ghost:
cd /var/www/ghost && ghost install
Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?

Assumptions based on all that…

  • Prompts have been disabled, all options must be provided via command line flags: The ghost installer appears to think it’s running in a non-interactive session, and needs to be provided all the necessary options as command line arguments.
  • The "url" argument must be of type string. Received undefined: This explains why I’m getting errors that the url parameter was not set during the installation, and it’s a required parameter.
  • So…now to figure out how to get ghost install to run the way I am trying, within a shell, in an interactive mode. Open to ideas, have tried things like:
  1. starting the script on the server with bash -i (didn’t work.)
  2. opening the ssh session using -tt to force pseudo emulation (didn't work) when ghost install ran and hit enter Blog URL it didn't accept characters and continue
  3. opening the ssh session using -tt to force pseudo emulation AND run the ghost install script within screen but AGAIN when ghost install ran and hit enter Blog URL it didn't accept characters and continue (eg didn't work)
  4. opening the ssh session using -tt to force pseudo emulation AND run the ghost install script using tmux but AGAIN when ghost install ran and hit enter Blog URL it didn't accept characters and continue (eg didn't work)

Log file

Here is output from the installer

Here’s output from the ghost installer:

] Getting download information [started]
[16:35:07] Getting download information [completed]
[16:35:07] Downloading [started]
[16:35:11] Downloading [completed]
[16:35:11] Installing dependencies [started]
[16:35:12] → yarn install v1.22.19
[16:35:12] → [1/5] Validating package.json...
[16:35:12] → [2/5] Resolving packages...
[16:35:14] → [3/5] Fetching packages...
[16:36:00] → [4/5] Linking dependencies...
[16:36:26] → [5/5] Building fresh packages...
[16:36:28] → info This package requires node-gyp, which is not currently installed. Yarn will attempt to automatically install it. If this fails, you can run "yarn global add node-gyp" to manually install it.
[16:36:29] → [1/4] Resolving packages...
[16:36:35] → [2/4] Fetching packages...
[16:36:36] → [3/4] Linking dependencies...
[16:36:37] → [4/4] Building fresh packages...
[16:36:37] → success Installed "node-gyp@9.4.0" with binaries:
[16:36:37] →       - node-gyp
[16:36:38] → info This module is OPTIONAL, you can safely ignore this error
[16:36:41] → success Saved lockfile.
[16:36:41] → Done in 89.01s.
[16:36:41] Installing dependencies [completed]
[16:36:41] Downloading and installing Ghost v5.63.0 [completed]
[16:36:41] Finishing install process [started]
[16:36:41] Linking latest Ghost and recording versions [started]
[16:36:41] Linking latest Ghost and recording versions [completed]
[16:36:41] Linking latest Casper [started]
[16:36:41] Linking latest Casper [completed]
[16:36:41] Finishing install process [completed]
[16:36:41] Configuring Ghost [started]
[16:36:41] Configuring Ghost [failed]
[16:36:41] → Prompts have been disabled, all options must be provided via command line flags
[16:36:41] Setting up instance [started]
[16:36:41] Setting up instance [failed]
[16:36:41] → The "url" argument must be of type string. Received undefined
[16:36:41] Setting up "ghost" system user [started]
[16:36:41] Creating "ghost" system user [started]
+ sudo useradd --system --user-group ghost
[16:36:41] Creating "ghost" system user [completed]
[16:36:41] Giving "ghost" user ownership of the /content/ directory [started]
+ sudo chown -R ghost:ghost /var/www/ghost/content
[16:36:41] Giving "ghost" user ownership of the /content/ directory [completed]
[16:36:41] Setting up "ghost" system user [completed]
[16:36:41] Setting up "ghost" mysql user [started]
[16:36:41] Setting up "ghost" mysql user [skipped]
[16:36:41] Setting up Nginx [started]
[16:36:41] Setting up Nginx [failed]
[16:36:41] → The "url" argument must be of type string. Received undefined
[16:36:41] Setting up SSL [started]
[16:36:41] Setting up SSL [skipped]
[16:36:41] → Nginx setup task failed, skipping SSL setup
[16:36:41] Starting Ghost [started]
[16:36:41] Starting Ghost [failed]
[16:36:41] → The content folder is not owned by the current user.
Ensure the content folder has correct permissions and try again.
One or more errors occurred.

1) SystemError

Message: Prompts have been disabled, all options must be provided via command line flags


2) undefined

TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received undefined

3) undefined

TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received undefined

4) SystemError

Message: The content folder is not owned by the current user.
Ensure the content folder has correct permissions and try again.

Debug Information:
    OS: Ubuntu, v22.04.3 LTS
    Node Version: v18.17.1
    Ghost Version: 5.63.0
    Ghost-CLI Version: 1.24.2
    Environment: production
    Command: 'ghost install'

Try running ghost doctor to check your system for known issues.

You can always refer to https://ghost.org/docs/ghost-cli/ for troubleshooting.

Love open source? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org

- Inspecting operating system
- Checking for deprecations

[16:36:42] Checking system Node.js version [started]
[16:36:42] Checking system Node.js version - found v18.17.1 [title changed]
[16:36:42] Checking system Node.js version - found v18.17.1 [completed]
[16:36:42] Ensuring user is not logged in as ghost user [started]
[16:36:42] Ensuring user is not logged in as ghost user [skipped]
[16:36:42] Checking if logged in user is directory owner [started]
[16:36:42] Checking if logged in user is directory owner [skipped]
[16:36:42] Checking current folder permissions [started]
[16:36:42] Checking current folder permissions [completed]
[16:36:42] Validating config [started]
[16:36:42] Validating config [failed]
[16:36:42] → Config file is not valid JSON
[16:36:42] Checking content folder ownership [started]
[16:36:42] Checking content folder ownership [completed]
[16:36:42] Checking memory availability [started]
[16:36:42] Checking memory availability [completed]
[16:36:42] Checking binary dependencies [started]
[16:36:42] Checking binary dependencies [completed]
One or more errors occurred.
Debug Information:
    OS: Ubuntu, v22.04.3 LTS
    Node Version: v18.17.1
    Ghost Version: 5.63.0
    Ghost-CLI Version: 1.24.2
    Environment: production
    Command: 'ghost start'

1) Validating config

Error detected in the production configuration.

Message: Config file is not valid JSON


Try running ghost doctor to check your system for known issues.

You can always refer to https://ghost.org/docs/ghost-cli/ for troubleshooting

Technical details

This is automatically output by Ghost-CLI if an error occurs, please copy & paste:

Bug submission checklist

Please fill out this checklist to acknowledge that you followed the requirements to submit a bug report.

  • [√] Tried to find help in the forum & docs
  • [√] Checked for existing issues
  • [√] Attached log file
  • [√] Provided technical details incl. operating system
@markstos
Copy link
Contributor

markstos commented Oct 3, 2023

When you say the CLI "has issues", could you be specific what those are?

What was the problem was supplying all details as command line arguments?

In your blog post, it appears that you are reporting that the script is working.
https://danielraffel.me/2023/09/05/updating-ghost-on-a-google-cloud-micro-instance/

@danielraffel
Copy link
Author

That's correct, my script is working. I ended up worked around the issues I stumbled upon.

What I wanted to do:

  • have a script on my local, client machine generate credentials (mysql p/w, root p/w, instance name, ssh keys, etc and sync to Google Secret Manager) and create a new VM instance using some of those details and SSH into the server (for the purpose of creating a VM and setting it up with Ghost)
  • have the server run a script that was downloaded from GitHub and execute it on the server with the SSH shell opened (for the purpose of monitoring installing Ghost on the server and fetching data securely from Google Secret that was originally generated on the local, client machine and synced to the cloud so the server could configure ghost)
  • my original intention was to allow the server to simply run ghost install and have the user interact with the CLI and complete the setup (eg define the URL, what they want to install, etc) however, this was not possible...herein lies the issue: no matter how I opened the ssh terminal I could not figure out how to get the CLI to respond to interactive prompts

What I ended up doing:

  • have a script on my local, client machine generate credentials (mysql p/w, root p/w, instance name, ssh keys, etc) ALSO ask the user for their blog URL and if they want to configure mailgun (and sync those settings to Google Secret Manager) and THEN create a new VM instance using some of those details and SSH into the server (for the purpose of creating a VM and setting it up with Ghost -- since the CLI is not interactive in the SSH shell probably due to some PTY issue I had to collect all the custom data locally)
  • have the server run a script that was downloaded from GitHub and execute it on the server with the SSH shell opened (for the purpose of monitoring installing Ghost on the server and fetching data securely that was generated on the local, client machine and synced to the cloud so the server could configure ghost)
  • while I stated before my original intention was to allow the server to simply run ghost install and have the user interact with the CLI and complete the setup (eg define the URL, what they want to install, etc) this was not possible...so, I fetched ghost install parameters from Google Secret Manager and passed them using --no-prompt

Technically, I was able to work around this. But, it does appear something with the CLI is not allowing it to be run interactively the way I was attempting. LMK if that makes more sense and/or if you have any further questions.

@markstos
Copy link
Contributor

markstos commented Oct 6, 2023

Thanks for the details. It'snot clear there's a bug in Ghost-CLI here.

It works in the normal interactive case and as you mentioned, for the non-interactive case, command line options can be passed.

It seems like if you wanted Ghost to prompt users for answers, then it would be the responsibility of your software to set up the environment so that the terminal is interactive. Sometimes the expect utility is used for jobs like this.

@danielraffel
Copy link
Author

I debated using expect but was passing sensitive passwords and didn't feel comfortable implementing a setup experience that way. Since other interactive prompts and CLIs worked fine for me in a remote shell (and Ghost CLI did not) I figured I'd report it. I'll leave it to folks like you who are maintaining this to decide whether you want to investigate it further. Thanks for replying. And, glad I was motivated to work around the issue (was impressed how robust the CLI is tbh was quite easy to pass it everything I needed to.)

@markstos
Copy link
Contributor

markstos commented Oct 6, 2023

@danielraffel Thanks for your sharing your code and your enthusiasm to make it easier for more people to get free Ghost hosting on Google Cloud. I'm not a Ghost CLI maintainer myself.

It's interesting here that some other interactive CLIs and prompts worked for you when Ghost's CLI does not. Maybe Ghost's CLI does indeed have a challenge between switching between interactive and non-interactive terminal handling.

Copy link

github-actions bot commented Feb 4, 2024

Our bot has automatically marked this issue as stale because there has not been any activity here in some time. The issue will be closed soon if there are no further updates, however we ask that you do not post comments to keep the issue open if you are not actively working on a PR. We keep the issue list minimal so we can keep focus on the most pressing issues. Closed issues can always be reopened if a new contributor is found. Thank you for understanding 🙂

@github-actions github-actions bot added the Stale label Feb 4, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants