Skip to content

v0.32.0

Choose a tag to compare

@github-actions github-actions released this 04 Sep 13:18
4af27b3

Added

  • A launch that attaches to a workspace devpod already has now says how far
    behind its checkout is.
    dl owner/repo@branch against a running workspace
    runs no git and never has -- that is the decision that makes a hot attach hot --
    so the checkout inside the container is whatever you left there, and nothing
    said so at the moment you were about to conclude something from it. One session
    went the whole way to "this devcontainer boots correctly" against a container
    built before the repository had a .devcontainer/ at all.

    The line is computed from dl's own clone and reaches no network:

    Workspace devlaunch-main-3j1t: its checkout is 37 commits behind origin/main as this
    workspace last fetched it, and a launch of a workspace devpod already has fetches
    nothing. Run 'git fetch' inside it, or 'dl <workspace> rm' and launch again, if you
    meant to run against the branch as it is now.
    

    A fetch on attach was the other candidate and would have been the wrong
    trade.
    The claim here is deliberately narrow: how the checkout stands against
    the origin/<branch> in that clone, of whatever age the last fetch left it. It
    is one rev-list against a local repository, single-digit milliseconds beside
    the 0.43s to 0.74s one devpod status already costs on the same path, and it
    cannot be wrong about a remote it never asked. Being behind a week-old ref is
    already the whole of what points you at git fetch or rm.

    Commits of your own are named as yours rather than counted as staleness, and
    four shapes stay silent: a checkout that agrees with its ref, one that is only
    ahead, a workspace whose clone is gone, and dl <workspace-id> by bare name,
    which carries no branch to be behind.

  • Every devpod up says whether it forwarded dotfiles, naming the repository
    and script it passed or saying that devpod's context options name none. dl
    reads DOTFILES_URL from devpod context options and from nowhere else -- not
    from the process environment, and not from ~/.devpod/config.yaml, which it only
    ever stats -- and it used to forward or omit the flags in silence either way.
    That silence is what turned one report of "the dotfiles never landed" into a
    fortnight of three plausible causes and no observation to cut between them. An
    attach that runs no up prints neither line, because it asked devpod for
    nothing.

  • docs/cli.md now names the cause of inject agent … exit status 126. devpod
    picks its agent binary by globbing uname -a for arm, and uname -a carries
    the container's hostname, so a workspace whose branch contains alarm, warm,
    charm, swarm, harm or armature gets the arm64 agent on an x86 host and a
    launch that dies saying only "not executable". dl writes the workspace id into
    that hostname itself, so it is one of the ways the name gets there. The entry
    carries the one-line check, the way to unblock a container that is already in
    that state, and the reason a recreate undoes it. The match itself is devpod's and
    is not fixed here.

Changed

  • dl <ws> reset stopped describing itself as a clean slate. Its help line and
    the README table said "Clean slate: remove everything, recreate", which reads as
    a promise about the checkout that reset does not keep: it passes devpod's
    --reset, and the source removal that flag additionally performs applies only to
    a workspace devpod cloned itself, where dl hands devpod a local folder. Both
    now say what it does -- recreate the container and its volumes -- and
    docs/cli.md and docs/workspaces.md gained the sentence that rm is the only
    verb which refreshes git state.

Fixed

  • dl --prune reclaims the per-workspace launch locks, which nothing short
    of --purge removing the whole cache directory had ever reached. Two dl runs
    launching one workspace serialize on an empty file under
    <cache>/devlaunch/launch-locks/<workspace-id>.lock; every workspace ever
    launched left one and no removal path took it away. Measured on one host: 18 of
    26 entries named no workspace devpod list still returns, against 8 live
    workspaces, the oldest three weeks old.

    Zero bytes of disk, and still the thing worth fixing. A directory that only
    ever grows is one nobody can read as a description of anything, and "nothing
    devlaunch causes to exist accumulates unreclaimed" is the rule the rest of the
    cleanup contract is written to.

    The precondition is the volumes' precondition, asked of the same listing: no
    workspace devpod list returns carries that id, re-asked under the acting
    pass's own second listing so the approved set can shrink between the plan and
    the act and can never grow.

  • Unlinking a lock file is safe now, which it was not before. Removing an
    flock'd file is the self-defeating move: a process holding the old inode
    excludes nobody, while new arrivals lock a fresh file at the same path and walk
    past it, and two devpod ups of one workspace run against each other. The rule
    used to be that no lock file is ever deleted, which is what made the leak
    above permanent.

    What replaced the rule is one question asked after every flock, on both
    sides: is the path still naming the inode I just locked? An acquisition that
    has lost its file queues again against the live one rather than believing
    itself alone, and a sweep that has lost its file re-opens rather than unlinking
    whatever the path names by then. Both halves are needed. A sweep that only took
    the lock would still have unlinked a live launch's file, because an inode
    somebody else already unlinked has no holders and locking one always succeeds.

    The unlink is then performed while holding the lock, and never queues for it: a
    lock a launch is holding is left standing, reported as held, and reclaimed by
    the next prune. That is not counted as a failure and does not change the exit
    code, because it is the guard working.

    --purge is not the only other unlinker, it is the other unlinker that holds
    no lock.
    It removes the cache directory entire, launch locks with it, which is
    what makes "somebody replaced this path" an ordinary event here rather than a
    devlaunch bug, and why the question above is asked every time rather than as a
    belt over a brace.

  • devpod's own per-workspace lock is left alone, deliberately, and the
    cleanup contract now says so in a table row rather than by omission. The same
    measurement found 70 of 78 stale entries under
    ~/.devpod/contexts/default/locks. They stay: it is another program's lock,
    taken by processes devlaunch does not run, and the revalidation above is a
    promise devlaunch can only make about a file only devlaunch opens. It is the
    same file dl <ws> kill has always been careful never to unlink.