gcloud ssh and commands with parameters - google-compute-engine

I'm having issues trying to execute a command over ssh using gcloud. This works perfectly when I execute from my Mac:
gcloud compute ssh instanceName --command="cd /folder; ls"
However, when I try to run that from Ubuntu inside one of the VMs, I get the following error:
ERROR: (gcloud.compute.ssh) unrecognized arguments: /folder; ls
Sounds like it is splitting the command by spaces. I tried different options like using single quotes, use vars, etc., but nothing worked for me.
What is the correct way to do it?

I found the issue. If you install from the Debian packages following this instructions:
https://cloud.google.com/sdk/#debubu
it will install an old version of gcloud. After installing using these instructions:
https://cloud.google.com/sdk/#nix
I got the latest version (0.9.83) and was able to execute the command without issues.

For me it's fixed by changing single-quotes to double-quotes.
I changed
gcloud compute ssh --zone us-east1-b instance-1 --command 'echo hello'
to
gcloud compute ssh --zone us-east1-b instance-1 --command "echo hello"

Related

OpenSSH tcl package

I am trying to replace a tcl/Expect script that calls ssh from Windows. We are upgrading to a 64-bit OS and Expect does not work with 64 bit Windows. I am trying to run the code found on this page but I cannot get it to recognize the ssh command in the third line.
set ssh [open "|ssh -tt -q -o {StrictHostKeyChecking no} $user#$host /bin/sh" r+]
OpenSSH is installed and I can run ssh commands from the windows command line, but I cannot do it from tcl. I am assuming I need to install an OpenSSH package, but I can't find any information on how to do it or where to get it.

gcloud: command not found when starting Cloud SQL Auth proxy with docker and container optimised OS

I'm trying to set-up a Cloud SQL Auth proxy with a Cloud SQL for MySQL instance.
I'm following this guide but without success.
so I'm creating a new VM instance. Once it has been created I'm running the following command in the cloud shell
gcloud beta compute ssh --zone "europe-west2-c" "nameinstance" --tunnel-through-iap --project "my_project"
From what I understand this allow me to connect to my instance. Then I'm running the following command:
docker pull gcr.io/cloudsql-docker/gce-proxy:1.19.1
all good. then I'm kind of lost as when entering gcloud sql instances describe Cloud_SQL_instance_name I got the following error gcloud: command not found
and when entering docker run -d \\ -p 127.0.0.1:3306:3306 \\ gcr.io/cloudsql-docker/gce-proxy:1.19.1 /cloud_sql_proxy \\ -instances=sql_connection_name=tcp:0.0.0.0:3306 I have the following error docker: invalid reference format.
Ultimately, and if I'm right, I should be able to execute successfully the following command mysql -u USERNAME -p --host 127.0.0.1
Container Optimized OS (or COS) target is simple: run containers. That's all. All the other capacity of linux have been deactivated, to keep the kernel small, to reduce the attack surface, and to limit the point of failure (with third party binaries, like gcloud).
Thus, run container with docker (or docker-containerd).
# interactive mode
docker run -ti google/cloud-sdk:latest gcloud version
# Script mode
docker run --entrypoint gcloud google/cloud-sdk:latest version
It works as is in startup script. If you log into the VM and want to run these commands, add a sudo before to have the permission to run the binaries.
So, you will be able to run Cloud SQL proxy in a container, Gcloud in a container, and also MySQL client in a container. Forget the fact to run something without container (and docker run command). And think also to redirect the port correct when you run your containers.

Google Compute Engine: how to set hostname permanently?

How do I set the hostname of an instance in GCE permanently? I can set it via hostname,but after reboot it is gone again.
I tried to feed in metadata (hostname:f.q.d.n), but that did not do the job. But it should work via metadata (https://github.com/GoogleCloudPlatform/compute-image-packages/tree/master/google-startup-scripts).
Anybody an idea?
The most simple way to achieve it is creating a simple script and that's what I have done.
I have stored the hostname in the instance metadata and then I retrieve it every time the system restarts in order to set the hostname using a cron job.
$ gcloud compute instances add-metadata <instance> --metadata hostname=<new_hostname>
$ sudo crontab -e
And this is the line that must be appended in crontab
#reboot hostname $(curl --silent "http://metadata.google.internal/computeMetadata/v1/instance/attributes/hostname" -H "Metadata-Flavor: Google")
After these steps, every time you restart your instance it will have the hostname <new_hostname>.
You can check it in the prompt or with the command: hostname
You need to remove the file /etc/dhcp/dhclient.d/google_hostname.sh
rm -rf /etc/dhcp/dhclient.d/google_hostname.sh
rm -rf /etc/dhcp/dhclient-exit-hooks.d/google_set_hostname
It's worth noting that this script is needed in order to run gcloud beta compute instances create with the --hostname flag. If this script is absent on a base image, new VM instances will preserve the source hostname/FQDN!
Edit rc.local
sudo nano /etc/rc.local
Add your line under the rest:
hostname *your.hostname.com*
Make sure to run the following after for the script to be executed
chmod +x /etc/rc.d/rc.local
Reboot, and profit.
That isn't possible. Please take a look at this answer. The following article explains that the "hostname" is part of the default metadata entries and it is not possible to manually edit any of the default metadata pairs. As such, you would need to use a script or something else to change the hostname every time the system restarts, otherwise it will automatically get re-synced with the metadata server on every reboot.
You can find information on startup scripts for GCE in this article. You can visit this one for info on how to apply the script to an instance.
You can also create a simple startup-script to do the jobs:
$ gcloud compute instances add-metadata <instance-name> --zone <instance-zone> --metadata startup-script='#! /bin/bash
hostname <hostname>'
Notice that if you already have a startup-script you need to add to the existing startup-script below command or you will replace all the startup-script:
$ hostname instance-name
I was lucky to set hostname at GCE running CentOS.
Source: desantolo.com
Click EDIT on your instance
Go to "Custom metadata" section
Add hostname + your.hostname.tld (change "your.hostname.tld" to your actual hostname
run curl --silent "http://metadata.google.internal/computeMetadata/v1/instance/attributes/hostname" -H "Metadata-Flavor: Google"
run sudo env EDITOR=nano crontab -e to edit crontab
add line #reboot hostname $(curl --silent "http://metadata.google.internal/computeMetadata/v1/instance/attributes/hostname" -H "Metadata-Flavor: Google")
On your keyboard Ctrl + X
On your keyboard hit Y
On your keyboard hit Enter
run reboot
after system rebooted, run hostname and see if your changes applied
Good luck!
If anyone finds this solution does not work for them on GCS instance. Then I suggest you try using exit hooks as described by Google Support.
In fact, some distributions of Linux like CentOS and Debian use
dhclient-script script to configure the network parameters of the
machine. This script is invoked from time to time by dhclient which is
dynamic host configuration protocol client and provides a means for
configuring one or more network interfaces using the DHCP protocol,
BOOTP protocol, or if these protocols fail, by statically assigning an
address.
The following text is a quote from the man (manual) page of
dhclient-script:
After all processing has completed, /usr/sbin/dhclient-script
checks for the presence of an executable
/etc/dhcp/dhclient-exit-hooks script, which if present is invoked using the ´.´ command. The exit status of
dhclient-script will be passed to dhclient-exit-hooks in the exit_status shell variable, and will always be zero
if the script succeeded at the task for which it was invoked. The rest of the environment as described previ‐
ously for dhclient-enter-hooks is also present. The /etc/dhcp/dhclient-exit-hooks script can modify the valid of
exit_status to change the exit status of dhclient-script.
That being said, by taking a look into the code snippet of
dhclient-script, we can see the script checks for the existence of an
executable /etc/dhcp/dhclient-up-hooks script and all scripts in
/etc/dhcp/dhclient-exit-hooks.d/ directory.
ETCDIR="/etc/dhcp"
193 exit_with_hooks() {
194 exit_status="${1}"
195
196 if [ -x ${ETCDIR}/dhclient-exit-hooks ]; then
197 . ${ETCDIR}/dhclient-exit-hooks
198 fi
199
200 if [ -d ${ETCDIR}/dhclient-exit-hooks.d ]; then
201 for f in ${ETCDIR}/dhclient-exit-hooks.d/*.sh ; do
202 if [ -x ${f} ]; then
203 . ${f}204 fi
205 done
206 fi
207
208 exit ${exit_status}209 }
Therefore, in order to modify the hostname of your Linux VM you can
create a custom script with .sh extension and place it in
/etc/dhcp/dhclient-exit-hooks.d/ directory. If this directory does not
exist, you can create it. The content of the custom script will be:
hostname YourFQDN.sh
>
be sure to make this new .sh file executable:
chmod +x YourFQDN.sh
Source: (https://groups.google.com/d/msg/gce-discussion/olG_nXZ-Jaw/Y9HMl4mlBwAJ)
Im not sure I understand Adrián's answer. It seems overly complex since you have to run a script each boot why not just use hostname?
vi /etc/rc.local
add:
hostname your_hostname
thats it. tested and working. no need to fiddle with metadata and such.
Non-cron/metadata/script solution.
Edit /etc/dhclient-(network-interface).conf or create one if it doesn't exist.
Example:
sudo nano /etc/dhclient-eth0.conf
Then add the following line, replacing the desired FQDN between the double quotes:
supersede host-name "hostname.domain-name";
Persists between reboots and hostname and hostname -f works as intended.
Tested on Debian.
The dhclient sets the hostname using DHCP
You can override this by creating a custom hook script in /etc/dhcp/dhclient-exit-hooks.d/custom_set_hostname that would read the hostname from /etc/hostname:
if [ -f "/etc/hostname" ]; then
new_host_name=$(cat /etc/hostname)
fi
The script must have the execute permission.
It's important to set the new_host_name variable and not calling the hostname command directly as any call to the hostname command will be overriden by another hook or the dhclient-script which uses this variable
When creating a VM, you can specify a custom FQDN hostname as an optional parameter. This feature is currently in Beta.
$ gcloud beta compute instances create INSTANCE_NAME --hostname example.hostname
This should work across OSes, and prevent the need for workaround scripts.
More info in the docs.
-- Sirui (Product Manager, Google Compute Engine)
In my CentOS VMs I found that the script /etc/dhcp/dhclient.d/google_hostname.sh, installed by the google-compute-engine RPM, actually changed the hostname. This happens when the instance gets its IP address during boot.
While it's not the long-term solution I really want, for now I simply deleted this script. The hostname I set with hostnamectl now persists after a reboot.
The script is likely to be in exactly the same place in Debian/Ubuntu VMs, but of course I don't run any of those.
There is some hack you can do to achieve this as i did. Just do:
sudo chattr +i /etc/hosts
This command actually makes the file "(i)mmutable", which means even root can't change it (unless root does chattr -i /etc/hosts first, of course).
As above, you can undo this with sudo chattr -i /etc/hosts
Cheer!
An easy way to fix this is to set up a startup script with custom metadata.
Key :startup-script
Value:
#! /bin/bash
hostname <desired hostname>

Permission denied errors when creating app with custom OpenShift cartridge

I'm using OpenShift Origin and developing a cartridge for the first time. When my bin/install and bin/control scripts are running I've noticed "Permission denied" errors when they try to access anything in the cartridge usr dir. In the node platform.log I see the offending command that OpenShift runs looks like this (where my bin/control start tries to run a script in usr):
/sbin/runuser -s /bin/sh 5351e627ee5a934f290001d2 -c "exec /usr/bin/runcon 'unconfined_u:system_r:openshift_t:s0:c0,c1004' /bin/sh -c \"set -e; /var/lib/openshift/5351e627ee5a934f290001d2/mycart/bin/control start \""
Since the usr dir is a symlink I originally thought it was related to that, but now I think it's related to selinux (which I don't know much about). If I do a "ls -Z" on my app's cartridge dir the files are "system_u:object_r:openshift_var_lib_t:s0:c0,c1004" but the contents of the usr dir are "unconfined_u:object_r:default_t:s0", so it doesn't match what's in the above command.
I used the oo-admin-cartridge command to install the cartridge to my Origin VM.
Any ideas on how to fix this?
What I ended up doing was running "chcon -R -u system_u -t bin_t usr/" before installing the cartridge with oo-admin-cartridge. Built-in cartridges are not affected by this problem (checked nodejs), so I feel like it might be a oo-admin-cartridge bug. I would expect it to massage the selinux permissions instead of using whatever I provide.

Google Compute Engine Startup Script Cant Execute

I am having trouble getting the following startup-script to execute properly when launching a Compute Engine Instance (GCE).
#! /bin/bash
setup vncserver
vnc4server -geometry 1440x900 :1
export DISPLAY=:1
echo "completed"
The script is read by GCE but does not execute the commands and the log shows blank lines with a message in-between which is the key to the problem but I cant seem to solve it.
Log shows the following:
Feb 3 09:15:33 simpleapache3 startupscript: Running startup script /var/run/google.startup.script
Feb 3 09:15:34 simpleapache3 startupscript:
Feb 3 09:15:34 simpleapache3 startupscript: You will require a password to access your desktops.
Feb 3 09:15:34 simpleapache3 startupscript:
How do I get around the "You will require a password..." section?
Tried:
I tried adding in a password inside the script like this but no luck...
#! /bin/bash
#setup vncserver
vnc4server -geometry 1440x900 :1
myPassword123
export DISPLAY=:1
echo "completed"
Notes:
I have got VNC4SERVER already installed on the persistent disk I am adding.
If I ssh into the instance and run the commands manually they work perfectly and I am not asked for a password.
Any help would be greatly appreciated...
I suspect this is because the startup scripts run as root rather than your user.
This script works for me:
#! /bin/bash
echo "I am: " `whoami`
sudo -u briandorsey DISPLAY=:1 vnc4server -geometry 1440x900 :1
echo "completed"
Replace briandorsey with your username.
Also, don't forget to create a firewall rule to allow vnc traffic. This can be done via the Console or with gcutil:
gcutil addfirewall vnc2 --allowed=tcp:5901
This will allow traffic on port 5901 to all virtual machines in your project. See the firewall docs for information on how to limit access further.