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

issue with creating context in interactive mode (hcloud: context create is an interactive command) #819

Open
jnovermars opened this issue Jul 16, 2024 · 8 comments
Assignees
Labels

Comments

@jnovermars
Copy link

jnovermars commented Jul 16, 2024

TL;DR

not able to use HCLOUD_TOKEN while running hcloud create context

Expected behavior

when running HCLOUD_TOKEN="x" hcloud context create dummy this should work and use the token provided in the environment var.

Observed behavior

i get the error:

hcloud: context create is an interactive command

Minimal working example

we use this in our gitlab ci pipeline where hcloud is installed via brew brew install hcloud:

HCLOUD_TOKEN="${TF_VAR_hcloud_token}" hcloud context create gitlab-ci <<<"Y"

Log output

$ HCLOUD_TOKEN="${TF_VAR_hcloud_token}" hcloud context create gitlab-ci <<<"Y"
hcloud: context create is an interactive command
Cleaning up project directory and file based variables 00:01
ERROR: Job failed: exit code 1

Additional information

See commend as there the links are working

@jnovermars jnovermars added the bug label Jul 16, 2024
@jnovermars
Copy link
Author

While checking the issue and diving into the code i found the following, keep in mind i am not sure if this is the case and is just an assumption :)

While this already happened before and saw it was fixed in the past already multiple times i think it has been broken by the last update by @phm07 with the change from if !ui.StdoutIsTerminal() { to if !s.Terminal().StdoutIsTerminal() { in commit: 0db5046

I am not a go developer so this is just a suggestion and i see that it has been changed what could of course explain why? Is it not a better idea to skip the interactive check when the os environment variable is provided?

@apricote
Copy link
Member

Hey @jnovermars,

I can not reproduce the issue on the latest version or on main. I do use Linux though. You are running your gitlab-ci pipeline on macOS?

What is the output of the following commands?

  • hcloud version - To verify that you use an up to date version
  • which hcloud - To make sure that the expected binary from brew is used
  • echo $0 - To get the name of the current shell (probaly zsh on Mac)

For reproducing I used the following command:

$ HCLOUD_CONFIG=hcloud-cli-819.toml HCLOUD_TOKEN=$(openssl rand -hex 64 | head -c 64) bash -c "hcloud context create foo <<<'Y'"
The HCLOUD_TOKEN environment variable is set. Do you want to use the token from HCLOUD_TOKEN for the new context? (Y/n): Context foo created and activated

Its also not necessary to create a context in your CI pipeline, you can do everything with environment variables and or flags if you want to.

@jnovermars
Copy link
Author

jnovermars commented Jul 17, 2024

It is easy to reproduce it in docker, i runned the commands you asked:

docker build -t test-hcloud . && docker run test-hcloud bash -c "hcloud version && which hcloud && echo \$0"

hcloud version: hcloud v1.45.0
which hcloud: /home/linuxbrew/.linuxbrew/bin/hcloud
echo $0: bash

i quicky created a small version of our docker file, and you are totally right that for CI pipeline the commands could run without the context. But i found this and think this is a bug as the expectation is that it could run without TTY but still it is required.

I converted your command to run it in docker:

docker build -t test-hcloud . && docker run test-hcloud bash -c "HCLOUD_CONFIG=hcloud-cli-819.toml HCLOUD_TOKEN=\$(openssl rand -hex 64 | head -c 64) hcloud context create foo <<<'Y'"

The docker file:
Big disclaimer, this is a brutally stripped docker file and just for demo purposes to run the hcloud command

FROM ubuntu:24.04

ENV TZ="Europe/Amsterdam"
ENV DEBIAN_FRONTEND="noninteractive"

# Install updates and dependencies
RUN apt update -y && apt install --no-install-recommends -y -q \
        curl \
        git \
        nano \
        build-essential \
        wget \
        dirmngr \
        apt-transport-https  \
        gnupg \
        lsb-release  \
        ca-certificates \
        software-properties-common \
    && apt-get clean

## second stage: Brew
ENV HOMEBREW_NO_AUTO_UPDATE=1

# Install brew
RUN apt-get update && \
    apt-get install -y -q --allow-unauthenticated \
    git \
    sudo
RUN useradd -m -s /bin/zsh linuxbrew && \
    usermod -aG sudo linuxbrew &&  \
    mkdir -p /home/linuxbrew/.linuxbrew && \
    chown -R linuxbrew: /home/linuxbrew/.linuxbrew
USER linuxbrew
RUN /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

USER root
RUN chown -R $CONTAINER_USER: /home/linuxbrew/.linuxbrew
ENV PATH="/home/linuxbrew/.linuxbrew/bin:${PATH}"

USER linuxbrew
RUN brew update
RUN brew install gcc

USER root

## Setup linuxbrew user
RUN mkdir -p /home/linuxbrew/workspace
WORKDIR /home/linuxbrew/workspace

USER linuxbrew

## third stage: install packages

## Install Terraform/OpenTofu gitlab scripts
USER root
RUN apt update -y && apt install --no-install-recommends -y -q \
        idn2 \
        openssh-client \
    && apt-get clean

USER linuxbrew

## Install Packer, kubectl, hcloud, jq

RUN brew install hcloud

@jooola
Copy link
Member

jooola commented Jul 18, 2024

I agree that we should support non-interactive mode, I think have an "assume yes" to bypass any yes/no prompt would be helpful in this scenario. But this might require a broader change across the CLI to support a such a global flag.

@jooola
Copy link
Member

jooola commented Jul 25, 2024

This is currently low priority, as one can always use the HCLOUD_TOKEN environment variable when running a script. Using a context for a script seem to be a really specific use case.

@jnovermars
Copy link
Author

That is indeed the workaround we use now

@phm07
Copy link
Contributor

phm07 commented Aug 12, 2024

Creating a context in non-interactive mode would mean that you would have to pass the token as a command argument. This is potentially unsafe and bad practice, since the token would then be stored in your shell history, even if you deleted the context. (Edit: Getting it from the environment, like you suggested, would be viable though. We would still need an extra flag then)

As a workaround, you can manually create contexts by manually appending to ~/.config/hcloud/cli.toml. The config is structured in such a way that appending a context does not break it.

@phm07
Copy link
Contributor

phm07 commented Sep 16, 2024

@jnovermars Can you try installing hcloud with:
go install github.com/hetznercloud/cli/cmd/hcloud@token-from-env

Then you can try using the following command:
HCLOUD_TOKEN="x" hcloud context create dummy --token-from-env

This should allow you to create a context using the CLI in a non-interactive TTY. Although be beware that this is not the recommended method, as it will store your token plain on disk and just using the HCLOUD_TOKEN environment variable is more secure (and also usually more convenient) than using contexts.

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

4 participants