[HN Gopher] Do-nothing scripting: the key to gradual automation ...
___________________________________________________________________
Do-nothing scripting: the key to gradual automation (2019)
Author : tehnub
Score : 323 points
Date : 2025-02-07 19:48 UTC (1 days ago)
(HTM) web link (blog.danslimmon.com)
(TXT) w3m dump (blog.danslimmon.com)
| IanCal wrote:
| I'm a big fan of this approach.
|
| In general it's another way of defining interfaces around
| processes. Those processes _may_ be manually done or automated.
| But the interface can remain the same - this is quite powerful
| when it comes to automating steps.
|
| It's the same as you'd do with another system really.
|
| I've used this before with Google sheets being manually filled in
| -> automated with a script. And with Jira tickets being raised
| and then automatically picked up and processed. It lets you get
| started sooner, automated the most annoying parts and you never
| have to fully do it.
|
| Side benefit of do nothing scripts is that they can remain up to
| date more often as they can be more likely to be actually used
| than reading the docs.
| itomato wrote:
| Yes and for me this an another chance to use and share Jupyter
| notebooks.
|
| Describe the thing. Offer boilerplate, examples, or
| parameterized executables.
|
| The doc system that uses Notebooks de facto would be awesome.
| It's too heavy to add as a layer to a Cloud SaaS like
| Confluence and offers too many opportunities for escalations as
| is..
| dheera wrote:
| I would prefer if the script did the things that already are a
| command.
|
| It can confirm with the user: "Execute command (y/N)?"
|
| Fuck cutting and pasting stuff from one terminal into another
| terminal. That's also focus-intensive.
|
| Then prompt the user to do the manual stuff when it isn't yet a
| command:
|
| "Look up the e-mail address for foo. Paste it here:"
|
| "Put that shit in 1Password: Are you done (y/N)?"
| patcon wrote:
| I think the point is that it's a psychological hack to just
| get started. It's making a point, and the point is that it's
| even helpful without running the commands. Yeah, sure you can
| immediately make it run the command as soon as it exists --
| the article is not implying that that's wrong
| IanCal wrote:
| You also get to a point that's _functional_ but not
| _optimal_ very quickly. Improvements can then be added
| incrementally by different people as and when it 's
| worthwhile.
| IanCal wrote:
| Then automate those points as and when it's worth doing.
| Nobody is saying you can't do that, in fact it's a very key
| selling point of a do nothing script - you can very easily
| upgrade it to a do _something_ script.
|
| The alternatives are "do everything scripts" which get lost
| in dealing with how to automatically manage 1password, or
| documentation which is just a do nothing script that doesn't
| lead you through the checklist.
| Xmd5a wrote:
| >Fuck cutting and pasting stuff from one terminal into
| another terminal. This is the point of this approach. To
| offer incentives to turn into scripts maintenance procedures
| that come around often but for which there isn't enough
| budget.
|
| I think jupyter notebooks are better suited to fill this role
| since you can gradually turn a 100% markdown wiki document
| into a script and offer one-click execution.
| 0xfaded wrote:
| My not-so-humble opinion is that this type of incremental
| encoding of process as scripts results in a system built around
| process rather than a system that eats process. I'm all for a
| catalog of scripts automating common tasks. The moment those
| scripts start getting called by production services you're
| creating a huge mountain of tech debt for whoever is
| unfortunate enough to unpick the web of spaghetti.
|
| Further, because your human oriented process has now codified
| your system, changes to the system that's would be beneficial
| to a software system (i.e. dividing the system into components)
| are impossible. So incremental scale is achieved by stuffing
| more into the process, which then gets grafted onto the script
| monolith in a self protruding cycle.
| IanCal wrote:
| I'm confused as to what you're picturing.
|
| > The moment those scripts start getting called by production
| services
|
| Any of them with manual steps just can't, right?
|
| > Further, because your human oriented process has now
| codified your system, changes to the system that's would be
| beneficial to a software system (i.e. dividing the system
| into components) are impossible.
|
| Absolutely nothing stops you from changing these scripts -
| it's no different from having scripts in a package.json
|
| The alternatives are full automation, which pushes your
| issues to the max, or zero automation which is an odd point
| to be in.
| hinkley wrote:
| My previous approach was:
|
| 1) Capture the process as is
|
| 2) make the process pass a giggle test
|
| 3) make the process automatable
|
| Concurrent with 3 and 4:
|
| - use the process repeatedly and by as many people as possible
|
| - adapt the process to any misuse seen in the wild
|
| 4) automate the process
|
| Everybody will buy into steps 1&2, and most people will come
| around to 4, but doing step 3 usually will get you more people
| pushing for and understanding 4
|
| The limitation of your approach I will say is that if you can
| automate the beginning of a process or the end it's fine, but
| if you have two islands in the middle it doesn't work better
| than a CLI tool with prompts.
| dejj wrote:
| I see the mountain of "Zen and the Art of Motorcycle
| Maintenance" coming into view.
|
| The approach replaces Confluence instruction pages with semi-
| interactive walkthroughs (the conscious side).
|
| The other side is test automation: it starts with a big ball of
| overfitted Xpaths and undocumented steps. Those get re-
| discovered every time the application changes (the subconscious
| side).
|
| Hopefully, we reach the summit where we can execute quickly and
| still know how we got there and why.
| MattSayar wrote:
| I was looking for this article recently since it inspired my most
| recent script to POSSE to various websites [0]. Thanks for
| posting it again!
|
| [0] https://github.com/MattSayar/post_to_socials
| picture wrote:
| What does POSSE stand for?
| kawera wrote:
| https://indieweb.org/POSSE
| qwertox wrote:
| It's great, but it can't be interrupted.
|
| It would also be nice if it would show you all the steps
| beforehand, and then check each item as you progress. Sometimes
| it's good to actually prepare from a broader perspective.
|
| And it could log into a file as a summary.
|
| So much that could be improved, which is why the simplest
| solution might be the best.
| gertlex wrote:
| Are these actual criticisms of the article?
|
| And you leave us hanging: which solution is the "simplest
| solution"?
| codetrotter wrote:
| I think the simplest solution would be to just do what the
| article says and not do all that extra stuff. And I think
| that that's what they meant at the end of that comment too.
| qwertox wrote:
| Yes, this was what I meant. Sorry to your parent commenter
| for not being explicit.
|
| (Then again, I'd do this in Obsidian.)
| gertlex wrote:
| Gotcha. I totally agree with the sentiment, or rather I
| should say: all these thoughts come to mind when thinking
| about setting up partial automation for a process, and I
| regularly remind myself to keep to simple, and get
| something working.
|
| The hardest to resist is when you have a similar
| framework in place for another process, but getting a new
| process to use that framework is still going to take 4x
| longer (or whatever) than starting from scratch and
| getting the initial consistency that the do-nothing
| approach gives.
| IanCal wrote:
| You could do this with a nicer cli library, so you could show
| the checklist and running output of each stage, which would be
| nice regardless of what steps are automated.
|
| My main issue with that is that a do nothing shell script is so
| easy to get started with that it's hard _not_ to complete it,
| and your efforts may be better used automating one of the
| steps. You may get lost in a fun but not that productive
| quagmire of which TUI library and how to structure everything.
| vagab0nd wrote:
| > but it can't be interrupted
|
| I'm glad this is mentioned! This is why instead of a Bash
| script, I use a Makefile. Each step is a rule with a *.done
| name, that generates a .done file once it's done. I can
| interrupt it any time, modify the script to fix something, and
| `make` to resume.
|
| But writing that Makefile is a PITA. Is there a better
| solution?
| mwdomino wrote:
| I've just switched to using just
| https://github.com/casey/just for my makefiles that were
| really just a collection of small snippets and it's worked
| wonderfully
| mettamage wrote:
| I should just do this for waking up so that I won't be confused
| on my morning routine. In a sense, it's a rudimentary slide show
| szvsw wrote:
| It's an interactive slide show, but it also has forced the user
| into the CLI context, where they are likely to already bring a
| different type of attention and focus than if they were reading
| the exact same set of instructions in a markdown file somewhere
| in the org's repos. Not necessarily better or worse, just
| different due to simulating the experience of a CLI tool as a
| mechanism for prompting the user to take certain actions.
| mettamage wrote:
| Yep, I realize that I can make a diary program that basically
| asks me how I am doing
|
| I just never think to create cli applications
| RodgerTheGreat wrote:
| Crucially, the presentation constrains the user's progress to
| a linear sequence of actions, which makes it straightforward
| to eventually make some steps actually do work automatically
| or semi-automatically. If you started with a markdown
| checklist or a powerpoint slide deck for presenting the same
| information, the form-factor would not provide linearity and
| would not invite further automation.
| captnswing wrote:
| https://www.pyinvoke.org/
| qwertox wrote:
| > Invoke is a Python library for managing shell-oriented
| subprocesses and organizing executable Python code into CLI-
| invokable tasks. It draws inspiration from various sources
| (make/rake, Fabric 1.x, etc) to arrive at a powerful & clean
| feature set.
|
| Thank you for linking to it.
| notarobot123 wrote:
| > It lowers the activation energy for automating tasks
|
| Does that mean the "do-nothing script" should eventually have
| some automated steps that do-something?
|
| As a placeholder for future possible automation, this feels like
| the right balance between automation and efficiency. It allows
| you to make the first stab without investing too much and it
| leaves some low-hanging fruit for another time when the effort
| might be more obviously worthwhile. Thanks for sharing!
| Jtsummers wrote:
| Yes.
|
| > Each step of the procedure is now encapsulated in a function,
| which makes it possible to replace the text in any given step
| with code that performs the action automatically.
| tetha wrote:
| Yeah, I started to incorporate this into my own work.
|
| Like, sometimes you can automate 99% of a procedure, except like
| putting a secret into an so-far not automated secret management
| solution, or running a terraform apply that requires access to
| something that's not accessible from the automation just yet.
|
| Instead of giving up there, I now just go ahead and insert e.g.
| an `ansible.builtin.pause` with clear instructions to the user
| what to do, and when to continue the play. This might not be
| gloriously fully automated (yet), but it is so much better than
| having to do the other 12 things manually.
|
| Similar, we have "standard plays", which are just shell scripts
| to invoke ansible in some specific way. But those have started to
| accrue some user guidance and some do-nothing instruction steps
| as well. The database creation script asks you if you've added
| the database in the three other places upon startup, since it'd
| fail otherwise. Or a disk resize standard play asks you if you
| need to resize the disk on a failover cluster as well now?
|
| I would like to have these things fully automated, but having
| these simple scripts as guidance for admins is surprisingly
| valuable.
| linsomniac wrote:
| The author needs to watch my buddy Jack's talk: Stop Writing
| Classes: https://youtu.be/o9pEzgHorH0?si=FgZqFGQNQUU2iREQ
| PNewling wrote:
| Care to give a TL;DW for those of us not able to watch this at
| the moment?
| nerdponx wrote:
| The title I think gets the point across!
| linsomniac wrote:
| Yeah, I think if you are the choir, this is just going to
| be preaching. But, if you're an inexperienced developer and
| lean towards adding layers of abstraction, this might be
| useful. In fact, I just recommended this to a team of 2
| developers to watch and they found it quite valuable. They
| are experienced developers, but one of them leans strictly
| to procedural code, and the other leans toward object
| oriented, and they were struggling. This worked as a
| conversation point to talk about where it was appropriate
| to lean OO.
| Jtsummers wrote:
| Don't bother watching the video, it's an extended form blog
| that can be summarized in a few sentences and I regret
| wasting 15 minutes watching it at 2x speed. The relevant part
| for what GP seems to be pointing at:
|
| > Don't use a class that wraps one method (or one method and
| init).
|
| It's irrelevant to this particular blog article because while
| the classes start that way, they are expected to grow (if
| they don't, they probably don't need to be steps in your
| procedures and you can delete them). The author gives each
| class the same run method as an interface so the steps can be
| moved around into other procedures more easily (config with
| class instantiation, execute with a call to run).
|
| The speaker's point is generally valid, but like all advice
| should be considered in context and not taken as a thing to
| do (or not do) all the time.
| linsomniac wrote:
| Is it irrelevant to the code in question? In my career I've
| run into so much code that is over engineered for a
| potential future use case, that has just caused so much
| pain and suffering in the meantime, often that future use
| case never happens. And to quote another buddy of mine,
| Raymond, "stop committing atrocities". :-)
| linsomniac wrote:
| A lot has changed since 2019. That "do nothing" script can be fed
| to an LLM and it's going to be a pretty good starting point for
| automating it. For example, feeding the script to ChatGPT
| o3-mini-high produced this for one of the steps:
| class CreateSSHKeypairStep(object): def run(self,
| context): keyfile =
| os.path.expanduser("~/{0}_ssh_key".format(context["username"]))
| pubkey = keyfile + ".pub" if
| os.path.exists(keyfile): print("Key file {}
| already exists. Skipping generation.".format(keyfile))
| else: print("Generating SSH key pair (no
| passphrase) in {} and {}.".format(keyfile, pubkey))
| cmd = ["ssh-keygen", "-t", "rsa", "-f", keyfile, "-N", ""]
| subprocess.check_call(cmd) # Save the key
| filenames in the context for later use.
| context["keyfile"] = keyfile context["pubkey"] =
| pubkey wait_for_enter()
| do_not_redeem wrote:
| Part of the point of do-nothing scripting is letting humans use
| their judgement in edge cases. For example, if the file already
| exists, you might not want to reuse a private key, potentially
| creating a security vulnerability, as chatgpt has done here.
|
| Also it hallucinated (as usual) some extra args to ssh-keygen.
| linsomniac wrote:
| Which arguments did it hallucinate? [I]
| /tmp> "ssh-keygen" "-t" "rsa" "-f" foo "-N" ""
| Generating public/private rsa key pair. Your
| identification has been saved in foo [...]
| do_not_redeem wrote:
| Original script: ssh-keygen -t rsa -f ~/{0}
|
| Chatgpt's version: ["ssh-keygen", "-t",
| "rsa", "-f", keyfile, "-N", ""]
|
| It added `-N ''`, which means don't set a passphrase--a
| second potential security downgrade.
| linsomniac wrote:
| Ok, fair enough, I was thrown by your use of the word
| hallucination, which to me is used to describe picking
| things that don't exist, like if it had done "ssh-keygen
| -t rsa --add-public-keyfile-to-gitrepo-and-commit". In
| this case I had asked it to automate the do-nothing
| script, so I'd call this more of a "design decision" than
| a hallucination.
| linsomniac wrote:
| Note: ChatGPT didn't blindly reuse a private key:
| [N] /tmp> "ssh-keygen" "-t" "rsa" "-f" foo "-N" ""
| Generating public/private rsa key pair. foo already
| exists. Overwrite (y/n)?
|
| It seems to me like you are assuming ChatGPT is always going
| to be wrong (which in itself is not an unreasonable place to
| start), which is coloring your use of the tool.
| do_not_redeem wrote:
| These lines skip the call to ssh-keygen: if
| os.path.exists(keyfile): print("Key file {}
| already exists. Skipping generation.".format(keyfile))
| oasisaimlessly wrote:
| It seems to me like you are assuming ChatGPT is always
| going to be _right_ , which is coloring your use of the
| tool.
| linsomniac wrote:
| I mean, I did say that assuming it was wrong was not an
| unreasonable place to start, which I think makes my
| position quite clear. But, I'll clarify: I review all the
| code that ChatGPT produces before I use it. Sometimes
| this results in me asking it to revise the code,
| sometimes it results in me abandoning that code,
| sometimes it results in me learning something because it
| has produced better code than I had in my mind thinking
| about the problem, or it used code or libraries that were
| a "blind spot" for me. I've been programming in Python
| since the late 90s, and programming since the early '80s,
| but I'm not a programmer by day, so I definitely have
| blind spots. Even if I was a programmer, I'd admit I'd
| have blind spots.
|
| But: The LLMs can produce rather good code. They can
| cover a lot of typing and low to mid level design work
| from a short description. I'm bringing value to my
| company and my life by using this tool, plain and simple.
| bagok wrote:
| > security vulnerability
|
| This GPT did the thing it was supposed to do: produce an
| implementation using a previous script's structures and
| processes. I'd bet explaining the reasoning, discussing
| potential vulnerabilities, or changing the business
| processes, wasn't in the prompt. Or that metadata wasn't
| included in GP for brevity.
|
| But it has succeeded in sparking discussion, similar to
| rubber-duck debugging. A good org will look at this as a
| starting point, discuss the details, and iterate.
|
| > Also it hallucinated (as usual) some extra args to ssh-
| keygen.
|
| I don't see a hallucination here. I can confirm it works, and
| is correct on my system with OpenSSH on it.
|
| I assume you mean the slightly strange `["-N", ""]` argument
| pair? This tells ssh-keygen to create the file with no
| passphrase and no prompting for a passphrase.
| bshacklett wrote:
| There's no reason you can't do both. As another sibling comment
| mentions, llms will get you part of the way there, but often
| have things you still need to work out. This helps you get a
| framework in place first, so that you can take an iterative
| approach to the parts that actually require effort from a human
| to deal with.
| linsomniac wrote:
| Just to be clear, I wasn't advocating against the do-nothing
| script, I've done that many times myself in the past. In
| fact, ChatGPT suggested a hybrid approach in the full result,
| as it didn't have enough information to look up the e-mail
| address so that step remained largely unchanged.
| daxfohl wrote:
| No idea why this is getting downvoted. This seems like the
| perfect thing to use LLMs for. Isolated code that is mostly
| boilerplate, outside your primary domain, and doesn't require
| much maintenance. In the worst case, you just let the user
| choose between manual and automated at each step, and if
| automated, prompt the user to check the results before moving
| on.
| niemandhier wrote:
| The biggest hold up in automation for me usually are things that
| need to be done via a gui.
|
| I tried automatizing those with some tools intended for gui
| testing, but those solutions tend to be brittle and I just don't
| feel well if I cannot get a real success report.
|
| I'd be fretful for somthing that solves that problem.
| xp84 wrote:
| I love this! it encourages you to mentally define the steps. To
| me, the next step is to define the "inputs" and "outputs" that
| each step should have. Next after that in many cases would be
| "what to do or just what to suggest to the user if each of the
| steps fail." And at that point you have not only a nicely already
| function-based outline if you want to make it a real automation.
|
| It's a thought technology which I suspect will result in better
| final scripts than what I have tended to do, which is much more
| linear and requires a significant refactoring step at the end to
| avoid having one long function of poor quality.
| rpicard wrote:
| I like this way of thinking. I'm working on a bunch of
| automations right now and using GitHub actions.
|
| I find the idea of setting up "do nothing workflows" that I can
| compose and implement more thoroughly over time helpful. I'll
| probably put this into use.
| gertlex wrote:
| Is this very feasible with Github Actions? Or would you be
| combining with other approaches? i.e. my impression is there
| isn't any real "wait for user input to continue" that is part
| of github actions.
| rpicard wrote:
| My interpretation is really just having placeholder workflows
| that still require manual steps and maybe even print them out
| as text, but don't necessarily wait.
| dolmen wrote:
| This is an interesting approach.
|
| However the task used as an example just shows how provisionning
| SSH keys was insecure at that company. In fact the user should
| generate his private key by himself and just provide the public
| key to the sysadmin to inject it in the system to grant access.
| AT NO POINT THE SYSDAMIN SHOULD HAVE A COPY OF THE PRIVATE KEY,
| even temporary. So the 1Password step shouldn't even be
| necessary.
|
| By the way, I'm the author of github-keygen, a tool to automate
| the creation of SSH keys dedicated to GitHub access, and to setup
| SSH settings for that context.
|
| https://github.com/dolmen/github-keygen
| chuckadams wrote:
| Making unskilled users manage their keys themselves doesn't
| sound very secure either. That's the point of moving to a
| script.
| JimBlackwood wrote:
| > In fact the user should generate his private key by himself
| and just provide the public key to the sysadmin to inject it in
| the system to grant access.
|
| I always found this such an annoying step to implement. We've
| switched to certificate based authentication on SSH - no more
| moving around public keys. Really simplified the whole process!
| jodrellblank wrote:
| Certificates have a private key and a public key, and you
| keep the private key secret and move the public key around,
| so ... how is that different, technically and
| organizationally?
|
| What do you actually do, and how is it better?
| Jtsummers wrote:
| Past discussions (lots of comments):
|
| https://news.ycombinator.com/item?id=29083367 - 3 years ago (230
| comments)
|
| https://news.ycombinator.com/item?id=20495739 - 6 years ago (124
| comments)
| mamidon wrote:
| To be clear; you're supposed to have a separate shell open where
| you do these steps?
|
| MM, interesting idea.
| starkparker wrote:
| Ideally this documentation would also document the expected
| output, both toward identifying when the process has gone off the
| rails when doing it manually and making the steps testable once
| automated.
|
| Otherwise, it'd be trivially easy for an unfamiliar user (or the
| automated script) to ignore unclear errors or exit codes and
| march blindly to the next wait_for_enter().
| deadbabe wrote:
| Great in theory until some error or problem comes up and you
| don't know how to handle it.
| Jailbird wrote:
| I'd say that's about the process itself, not the script
| mirroring the process.
|
| Fix the process, fix the script. Onwards....
| __MatrixMan__ wrote:
| I bet you could adapt this for orchestrators besides a script.
| For instance if the goal is to eventually have it all running in
| Airflow, you could have a do-nothing DAG, which would be nice
| because your co-workers could see that you're already half-way
| through today's task, whereas separate python scripts don't know
| about each other. You could just use a `sleep infinity` to keep
| the task "running" until somebody manually sets it to "success".
| parentheses wrote:
| This approach always sounds great upon initial consideration but
| has a fatal flaw. It doesn't scale because people are lazy. Over
| time, slogs will always revert to their original form.
| avipars wrote:
| A good way of documenting processes for people that prefer to
| look at code than long PDfs
| tejtm wrote:
| Haven't had my coffee yet but this strike me as, "reinvent the
| Makefile". Which I have certainly used as a place to codify steps
| with benefits.
| parasti wrote:
| This is actually brilliant. This is a step above every list of
| instructions that I've ever made without committing to full-blown
| all-at-once automation.
| perpil wrote:
| I did something like this but it helps you build exact command
| lines or interact with AWS straight from your GitHub markdown. As
| a bonus, it very easily lets you prompt the user for inputs and
| pivot between different accounts. https://speedrun.cc
| hinkley wrote:
| I finally tried this an about a year so after it was first
| posted.
|
| Due to bugs in our toolchain we had a run book for hot fixes that
| was about twice as complicated as the normal release process.
|
| I never got the credit it deserved but it went from people only
| using it for sev 1 issues and "last mile" work in epics that were
| winding up, say once every ten weeks, to using it on average once
| a week and a couple times 3 in one week. We were able to dig a
| lot deeper into tech debt because not every single thing had to
| be a feature toggle.
|
| If you're at a small company where cloning prod data into preprod
| is easy, you won't see this sort of result. But I counted over
| 150 endpoints we talked to and I believe that averaged 3 per
| service. So that's a lot of datasets, and some of them ingested
| in a Kafka-before-Kafka-existed sort of manner. We had only one
| guy who would even try to clone prod data, he only had the time
| (and really energy) to do it once or twice a year, and that was
| much slower than our customers and features morphed. So it was
| down to fiddling with the blue-green deployment process and
| jmeter to figure out if we were close and how to measure
| success/failure before we went live.
|
| And in the end it was the fiddly error-prone build process that
| stymied people until I half-automated it.
|
| Later on as we ramped up its use I hunted down all of the URLs
| for the manual steps and put them in a lookup table in the tool,
| and ended up exposing them for the normal validation process we
| did for release sign off as well. Which made that process a
| little faster and less stressful for the coordinator (that
| process was annoying enough that we round robined it through
| three separate teams to share the load)
| throwpoaster wrote:
| Even though "toil" is a term of art, be careful using it around
| executives who are not SMEs.
|
| I once saw an SRE get managed out because he kept talking about
| "reducing toil" and his director eventually said, "he obviously
| didn't like toiling here so we helped him leave."
| oulipo wrote:
| Just did a slightly more elaborate version (mostly colors)
|
| run it with `uv run --script script.py`
| #!/usr/bin/env -S uv run --script # /// script #
| requires-python = ">=3.13" # dependencies = [ #
| "rich", # ] # /// # run using
| `./script.py` or `uv run --script script.py`
| import argparse from rich import print from
| rich.prompt import Prompt from rich.panel import Panel
| def print_title(text): print(Panel(f" {text}",
| style="green")) print("\n") def
| print_desc(text): print(f"[yellow] {text}[/yellow]")
| def print_command(text):
| print(f"[white]{text}[/white]") def
| user_input(prompt): print("\n") return
| Prompt.ask(f"\n[red] {prompt}[/red]") def
| wait_for_enter(dummy_flag): print("\n")
| print(Panel(f" Press enter to continue", title_align="center",
| style="blue")) input() class
| CreateSSHKeypairStep: def run(self, context):
| print_title("Generating SSH Key Pair")
| print_desc("Run:") print_command(f"ssh-keygen -t
| rsa -f {context['key_path']}/{context['username']}.pub")
| wait_for_enter(True) class GitCommitStep:
| def run(self, context): print_title("Committing
| SSH Key to Git Repository") print_desc("Run:")
| print_command(f"cp
| {context['key_path']}/{context['username']}.pub user_keys/")
| print_command(f"git commit {context['username']}")
| print_command("git push") wait_for_enter(True)
| class WaitForBuildStep: build_url =
| "http://example.com/builds/user_keys" def run(self,
| context): print_title("Waiting for Build Job to
| Finish") print_desc(f"Wait for the build job at
| {self.build_url} to finish") wait_for_enter(True)
| class RetrieveUserEmailStep: dir_url =
| "http://example.com/directory" def run(self,
| context): print_title("Retrieving User Email")
| print_desc(f"Go to {self.dir_url}")
| print_desc(f"Find the email address for user
| `{context['username']}`") context["email"] =
| user_input("Paste the email address and press enter")
| class SendPrivateKeyStep: def run(self, context):
| print_title("Sending Private Key") print_desc("Go
| to 1Password") print_desc(f"Paste the contents of
| {context['key_path']}/{context['username']} into a new document")
| print_desc(f"Share the document with {context['email']}")
| wait_for_enter(True) if __name__ == "__main__":
| parser = argparse.ArgumentParser(description="Automate SSH key
| setup and sharing process.")
| parser.add_argument("username", type=str, help="Username for whom
| the SSH key will be generated") parser.add_argument("
| --key-path", type=str, default=".", help="Path where the SSH key
| will be stored (default: .)") parser.add_argument("--
| extra-args", nargs="*", help="Additional arguments for future
| use") args = parser.parse_args()
| context = { "username": args.username,
| "key_path": args.key_path, "extra_args":
| args.extra_args or [] }
| procedure = [ CreateSSHKeypairStep(),
| GitCommitStep(), WaitForBuildStep(),
| RetrieveUserEmailStep(), SendPrivateKeyStep(),
| ] for step in procedure:
| step.run(context) print("[green]
| Done.[/green]")
| oulipo wrote:
| Here's a screenshot:
|
| https://imgur.com/a/MmViG7G
| iancmceachern wrote:
| I cannot overstate how big a fan i am of this approach.
|
| I've successfully applied this approach to so many projects. My
| favorite example is a $30 million surgical robot that was failing
| labs because of the "human factor".
| machine_ghost wrote:
| This same is also known by another name when it's used to teach
| new programmers: pseudo code.
|
| Sadly, because it's associated with learners/juniors, pseudo code
| gets a bad rap. But really, _all_ engineering is translating
| English into code ... which means almost _any_ complex operation
| (setting up a new employee 's account, or anything else) can be
| made clearer by utilizing such an "in-between English and code"
| step.
|
| In the article they used Python, but for all the important stuff,
| they didn't: they used English. A "do-nothing" script is really
| just a script where instead of converting pseudo code to code
| (like programmers normally do), you just leave the English/pseudo
| code in, and wrap it with a print.
| hnlmorg wrote:
| I get the point you're making but I cannot say I agree with it.
|
| Pseudo code is non-compilable text that's intended to
| illustrate a computer function.
|
| Whereas this is compilable code used to illustrate a human
| function.
|
| So in a sense, they're solving the exact opposite problems.
| layer8 wrote:
| I would use a checklist for that. Most wiki/notes/todo software
| supports checklists or checkboxes. It has the benefit that you
| can still see all steps at once, perform some steps out of order
| if the dependency isn't linear, and it can be simply part of your
| process documentation instead of having to find and run a script.
| It's also easier to edit.
|
| The article even mentions "just another checkbox checked".
| outofpaper wrote:
| This is a waste of energy as there a cleaner clearer more
| effective ways of dealing with this script. You can go much
| cleaner and just do a Markdown Slideshow. Alternatively allow for
| a little real automation and use something like Expect or
| Pexpect.
|
| https://pexpect.readthedocs.io/en/stable/overview.html
|
| Don't pretend to yourselves that presenting a series of
| instructions and only advancing on when someone clicks enter will
| prevent people hit enter.
|
| Even worse is someone missed up there's no going back. You have
| to either restart the whole process or you have to go and read
| over the python script.
|
| This is not something that prevents or helps with slog.
| aqueueaqueue wrote:
| Oh yeah! I've seen this pattern used at work. I don't have an
| opinion on if it is better than a checklist. The lack of will or
| time to automate affects a do nothing script as much as runbook.
___________________________________________________________________
(page generated 2025-02-08 23:00 UTC)