Skip to content

Rebuild and allow user SSH #2977

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

Merged
merged 1 commit into from
Jan 28, 2024
Merged

Conversation

FrostyX
Copy link
Member

@FrostyX FrostyX commented Nov 2, 2023

Implementation of fedora-copr/debate#6

Fixes: #2364

@FrostyX FrostyX marked this pull request as draft November 2, 2023 12:33
@FrostyX FrostyX added the WIP label Nov 2, 2023
@praiskup
Copy link
Member

praiskup commented Nov 6, 2023

Per @lachmanfrantisek claim, @nforro wants to be the early adopter! :-)

Copy link

@github-advanced-security github-advanced-security bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vcs-diff-lint found more than 10 potential problems in the proposed changes. Check the Files changed tab for more details.

@FrostyX FrostyX force-pushed the rebuild-and-keep-ssh branch from d8bf463 to f964c9b Compare December 3, 2023 20:42
@FrostyX
Copy link
Member Author

FrostyX commented Dec 3, 2023

There is still work to be done but can you please do a preliminary review @praiskup? I don't want to sink time in fine-tuning the details without knowing, that the general idea looks good.

What remains to be done:

  • There is a lot of valid linter errors that need to be fixed
  • Obtaining SSH keys from FAS (or fallback to a general textarea) is not there yet
  • I only tested in the docker-compose so far. Still requires some STG testing
  • Small bugs (mainly copr-builder show)
  • Some conceptual questions code TODOs, I am very much interested in your opinion

@@ -862,6 +865,8 @@ def add(cls, user, pkgs, copr, source_type=None, source_json=None,
copr_dir=copr_dir,
bootstrap=bootstrap,
isolation=isolation,
allow_user_ssh=allow_user_ssh,
ssh_public_key=ssh_public_key,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to have this in YAML/JSON format or something...? We
could have things like:
:

---
type: FAS
fas_user: xyzuser
---
type: plaintext
pub_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDj5HauAOur/6+...
---
type: online
url: https://github.com/praiskup.keys

We don't have to implement all the options in the web-UI right now, nor in cli.
But we can be "prepared".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds reasonable, not done yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this and it is probably not needed now. We IMHO still want one big textarea for user input and then parse the different (types of) keys somewhere in our code. Personally, I would do the parsing on backend (we have workers there) or even on builder. Because we can fetch the keys from FAS or URL right after that.

Right now only plaintext and one key is supported, so the value could only be

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDj5HauAOur/6+.

Seeing some other comments in the PR, we will probably implement support for multiple keys in this PR, so newline would be separator, e.g.

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDj5HauAOur/6+.
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDj5HauAOur/6+.

Once we start to support other methods, the input could be

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDj5HauAOur/6+.
FAS:xyzuser
https://github.com/praiskup.keys
GitHub:frostyx

We can always save the blob to the database as is and parse it when needed. That would be consistent with how e.g. copr:// external repositories work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now only plaintext and one key is supported

Huh, I've successfully tested before with multiple keys :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We IMHO still want one big textarea for user input and then parse the different (types of) keys somewhere in our code.

I'd prefer to have a separate text area in the future, rather than changing the field and start "guessing" the type of input.

My thought was to start doing it right away in the background -- aka giving the user a simple textarea for multi-line key-only input, converting it to the yaml thing in the background, and store into DB. This way we would have open doors for later enhancements without touching the old entries. But I agree that this is rather a nice to have thing, there are many such things.

@praiskup
Copy link
Member

praiskup commented Dec 4, 2023

This is a very exciting change. Thank you for the progress!

@praiskup
Copy link
Member

praiskup commented Dec 4, 2023

Can we have the per/user (maybe per arch) limit? I dont remember whether we decided to not implement it..

Copy link
Member Author

@FrostyX FrostyX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for the review. I updated almost everything but the PR is still WIP.

@@ -862,6 +865,8 @@ def add(cls, user, pkgs, copr, source_type=None, source_json=None,
copr_dir=copr_dir,
bootstrap=bootstrap,
isolation=isolation,
allow_user_ssh=allow_user_ssh,
ssh_public_key=ssh_public_key,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds reasonable, not done yet.

@FrostyX FrostyX force-pushed the rebuild-and-keep-ssh branch 2 times, most recently from 7a4cd5d to 7f0b348 Compare December 20, 2023 21:06
@FrostyX FrostyX force-pushed the rebuild-and-keep-ssh branch from 87e8c7e to 9fa616e Compare December 21, 2023 20:31
@FrostyX
Copy link
Member Author

FrostyX commented Jan 13, 2024

Thank you very much for the review @praiskup,
I addressed all your comments. Everything is in a separate commit for the reviewing convenience, I will squash them before merging.

no motd ...

I spent a couple of hours on this before Christmas and wasn't able to set up MOTD on the builders. And then @xsuchy suggested it might be a good idea not having MOTD because of cases like if $(ssh ... cat foo|head -n1) == "foo". So I put in the instructions to run copr-builder help instead.

@praiskup
Copy link
Member

if $(ssh ... cat foo|head -n1) == "foo"

But MOTD shouldn't affect stdout:

$ ssh batcave01.iad2.fedoraproject.org echo ahoj
ahoj

@praiskup
Copy link
Member

jakub to ping pavel and take a look at motd problems..

@@ -307,6 +318,9 @@ def _parse_results(self):
"""
Parse `results.json` and update the `self.job` object.
"""
if self.job.ssh_public_keys:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implication here deserves an inline comment :-)

@@ -683,6 +704,9 @@ def _collect_built_packages(self, job):
"""
self.log.info("Listing built binary packages in %s", job.results_dir)

if self.job.ssh_public_keys:
return "Public SSH access was enabled, no results were stored"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it safer to return empty dict here?

"{}/".format(dest),
"&>", log_filepath,
])
command = " ".join(command)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

if not x._task.get("ssh_public_keys"):
return None
return x.owner
super().__init__(predicate, limit, name="userssh")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/predicate/hasher/?

"""
Limit the number of builders that allow user SSH
"""
def __init__(self, _hasher, limit):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can drop the unused hasher argument I think.

<input type="hidden" name="allow_user_ssh" value="{{ allow_user_ssh }}">
{{ render_field(form.ssh_public_keys, label='Public SSH keys',
placeholder='Newline separated public SSH keys, e.g. ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDR+QU9...',
rows=8, cols=50) }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems damn awesome! :-) Can't wait for testing it.

@FrostyX FrostyX force-pushed the rebuild-and-keep-ssh branch from 1bf44bb to 153d521 Compare January 18, 2024 14:09
@praiskup
Copy link
Member

Small style issue:
Screenshot_20240118_164643

@praiskup
Copy link
Member

I'm a bit uncertain about the windows-like EOLs, in vim I see:

... praiskup.usersys.redhat.com^M

@praiskup
Copy link
Member

I tried to drop .ssh/authorized_keys file - checking what happens :-) - and it just finished the otherwise succeeding build. Is this OK?

@@ -51,6 +58,9 @@

COMMANDS = {
"rpm_q_builder": "rpm -q copr-rpmbuild --qf \"%{VERSION}\n\"",
"echo_authorized_keys": "echo {0} >> /root/.ssh/authorized_keys",
"set_expiration": "echo -n {0} > " + USER_SSH_EXPIRATION_PATH,
"cat_expiration": "cat {0}".format(USER_SSH_EXPIRATION_PATH),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should document here that we must be especially careful about error handling; users may replace the echo or cat commands, and (in theory) cause damage to the backend machine. This deserves documenting IMO (here ore in a later PR).

if self.job.ssh_public_keys:
self.log.info("Builder allowed user SSH, not downloading the "
"results for safety reasons.")
filter_ = ["+ success", "+ *.spec", "- *"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking ... what if user replaces the remote side (server) rsync binary. Can that trick the backend to download some unwanted stuff?

Ideas?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks quite dangerous. Should we maybe verify some checksum of the binary, or something like that? Same for the cat commands mentioned above? But maybe that leads to the same issue (i.e. we can't be sure that the checksum tool wasn't tampered with)?

@praiskup
Copy link
Member

Just a few comments above, otherwise it seems OK to squash and merge. The motd and other things can be done later.

@FrostyX
Copy link
Member Author

FrostyX commented Jan 21, 2024

Small style issue:

Do you want the instructions in the "SSH access to the builder" section to be indented to the right?

I'm a bit uncertain about the windows-like EOLs, in vim I see:
... praiskup.usersys.redhat.com^M

Hmm, I haven't encountered this. Where do you see the ^M characters?

"""
Find the user preference for the builder expiration.
"""
rc, out, _err = self.root_ssh.run_expensive(COMMANDS["cat_expiration"])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use run_expensive and check output length and/or timeout.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't use run because it doesn't return the output. So I kept run_expensive and added a timeout for it.

@FrostyX FrostyX force-pushed the rebuild-and-keep-ssh branch from 7d1741a to c5d0ca5 Compare January 26, 2024 11:54
@FrostyX
Copy link
Member Author

FrostyX commented Jan 26, 2024

Small style issue:
Screenshot_2024-01-26_12-55-04

I changed the style a bit.

Copy link
Member

@praiskup praiskup left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Debugging for users - obtain a builder, and give the user SSH there
2 participants