diff --git a/invokeai/app/services/config.py b/invokeai/app/services/config.py index a9a4a64f75..c119f2f74c 100644 --- a/invokeai/app/services/config.py +++ b/invokeai/app/services/config.py @@ -274,7 +274,7 @@ class InvokeAISettings(BaseSettings): @classmethod def _excluded(self) -> List[str]: # internal fields that shouldn't be exposed as command line options - return ["type", "initconf", "cached_root"] + return ["type", "initconf"] @classmethod def _excluded_from_yaml(self) -> List[str]: @@ -290,7 +290,6 @@ class InvokeAISettings(BaseSettings): "restore", "root", "nsfw_checker", - "cached_root", ] class Config: @@ -356,7 +355,7 @@ class InvokeAISettings(BaseSettings): def _find_root() -> Path: venv = Path(os.environ.get("VIRTUAL_ENV") or ".") if os.environ.get("INVOKEAI_ROOT"): - root = Path(os.environ.get("INVOKEAI_ROOT")).resolve() + root = Path(os.environ["INVOKEAI_ROOT"]) elif any([(venv.parent / x).exists() for x in [INIT_FILE, LEGACY_INIT_FILE]]): root = (venv.parent).resolve() else: @@ -403,7 +402,7 @@ class InvokeAIAppConfig(InvokeAISettings): xformers_enabled : bool = Field(default=True, description="Enable/disable memory-efficient attention", category='Memory/Performance') tiled_decode : bool = Field(default=False, description="Whether to enable tiled VAE decode (reduces memory consumption with some performance penalty)", category='Memory/Performance') - root : Path = Field(default=_find_root(), description='InvokeAI runtime root directory', category='Paths') + root : Path = Field(default=None, description='InvokeAI runtime root directory', category='Paths') autoimport_dir : Path = Field(default='autoimport', description='Path to a directory of models files to be imported on startup.', category='Paths') lora_dir : Path = Field(default=None, description='Path to a directory of LoRA/LyCORIS models to be imported on startup.', category='Paths') embedding_dir : Path = Field(default=None, description='Path to a directory of Textual Inversion embeddings to be imported on startup.', category='Paths') @@ -424,7 +423,6 @@ class InvokeAIAppConfig(InvokeAISettings): log_level : Literal[tuple(["debug","info","warning","error","critical"])] = Field(default="info", description="Emit logging messages at this level or higher", category="Logging") version : bool = Field(default=False, description="Show InvokeAI version and exit", category="Other") - cached_root : Path = Field(default=None, description="internal use only", category="DEPRECATED") # fmt: on def parse_args(self, argv: List[str] = None, conf: DictConfig = None, clobber=False): @@ -472,15 +470,12 @@ class InvokeAIAppConfig(InvokeAISettings): """ Path to the runtime root directory """ - # we cache value of root to protect against it being '.' and the cwd changing - if self.cached_root: - root = self.cached_root - elif self.root: + if self.root: root = Path(self.root).expanduser().absolute() else: - root = self.find_root() - self.cached_root = root - return self.cached_root + root = self.find_root().expanduser().absolute() + self.root = root # insulate ourselves from relative paths that may change + return root @property def root_dir(self) -> Path: diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 3de8c91b38..0000000000 --- a/shell.nix +++ /dev/null @@ -1,162 +0,0 @@ -{ pkgs ? import {} - , lib ? pkgs.lib - , stdenv ? pkgs.stdenv - , fetchurl ? pkgs.fetchurl - , runCommand ? pkgs.runCommand - , makeWrapper ? pkgs.makeWrapper - , mkShell ? pkgs.mkShell - , buildFHSUserEnv ? pkgs.buildFHSUserEnv - , frameworks ? pkgs.darwin.apple_sdk.frameworks -}: - -# Setup InvokeAI environment using nix -# Simple usage: -# nix-shell -# python3 scripts/preload_models.py -# python3 scripts/invoke.py -h - -let - conda-shell = { url, sha256, installPath, packages, shellHook }: - let - src = fetchurl { inherit url sha256; }; - libPath = lib.makeLibraryPath ([] ++ lib.optionals (stdenv.isLinux) [ pkgs.zlib ]); - condaArch = if stdenv.system == "aarch64-darwin" then "osx-arm64" else ""; - installer = - if stdenv.isDarwin then - runCommand "conda-install" { - nativeBuildInputs = [ makeWrapper ]; - } '' - mkdir -p $out/bin - cp ${src} $out/bin/miniconda-installer.sh - chmod +x $out/bin/miniconda-installer.sh - makeWrapper \ - $out/bin/miniconda-installer.sh \ - $out/bin/conda-install \ - --add-flags "-p ${installPath}" \ - --add-flags "-b" - '' - else if stdenv.isLinux then - runCommand "conda-install" { - nativeBuildInputs = [ makeWrapper ]; - buildInputs = [ pkgs.zlib ]; - } - # on line 10, we have 'unset LD_LIBRARY_PATH' - # we have to comment it out however in a way that the number of bytes in the - # file does not change. So we replace the 'u' in the line with a '#' - # The reason is that the binary payload is encoded as number - # of bytes from the top of the installer script - # and unsetting the library path prevents the zlib library from being discovered - '' - mkdir -p $out/bin - sed 's/unset LD_LIBRARY_PATH/#nset LD_LIBRARY_PATH/' ${src} > $out/bin/miniconda-installer.sh - chmod +x $out/bin/miniconda-installer.sh - makeWrapper \ - $out/bin/miniconda-installer.sh \ - $out/bin/conda-install \ - --add-flags "-p ${installPath}" \ - --add-flags "-b" \ - --prefix "LD_LIBRARY_PATH" : "${libPath}" - '' - else {}; - - hook = '' - export CONDA_SUBDIR=${condaArch} - '' + shellHook; - - fhs = buildFHSUserEnv { - name = "conda-shell"; - targetPkgs = pkgs: [ stdenv.cc pkgs.git installer ] ++ packages; - profile = hook; - runScript = "bash"; - }; - - shell = mkShell { - shellHook = if stdenv.isDarwin then hook else "conda-shell; exit"; - packages = if stdenv.isDarwin then [ pkgs.git installer ] ++ packages else [ fhs ]; - }; - in shell; - - packages = with pkgs; [ - cmake - protobuf - libiconv - rustc - cargo - rustPlatform.bindgenHook - ]; - - env = { - aarch64-darwin = { - envFile = "environment-mac.yml"; - condaPath = (builtins.toString ./.) + "/.conda"; - ptrSize = "8"; - }; - x86_64-linux = { - envFile = "environment.yml"; - condaPath = (builtins.toString ./.) + "/.conda"; - ptrSize = "8"; - }; - }; - - envFile = env.${stdenv.system}.envFile; - installPath = env.${stdenv.system}.condaPath; - ptrSize = env.${stdenv.system}.ptrSize; - shellHook = '' - conda-install - - # tmpdir is too small in nix - export TMPDIR="${installPath}/tmp" - - # Add conda to PATH - export PATH="${installPath}/bin:$PATH" - - # Allows `conda activate` to work properly - source ${installPath}/etc/profile.d/conda.sh - - # Paths for gcc if compiling some C sources with pip - export NIX_CFLAGS_COMPILE="-I${installPath}/include -I$TMPDIR/include" - export NIX_CFLAGS_LINK="-L${installPath}/lib $BINDGEN_EXTRA_CLANG_ARGS" - - export PIP_EXISTS_ACTION=w - - # rust-onig fails (think it writes config.h to wrong location) - mkdir -p "$TMPDIR/include" - cat <<'EOF' > "$TMPDIR/include/config.h" - #define HAVE_PROTOTYPES 1 - #define STDC_HEADERS 1 - #define HAVE_STRING_H 1 - #define HAVE_STDARG_H 1 - #define HAVE_STDLIB_H 1 - #define HAVE_LIMITS_H 1 - #define HAVE_INTTYPES_H 1 - #define SIZEOF_INT 4 - #define SIZEOF_SHORT 2 - #define SIZEOF_LONG ${ptrSize} - #define SIZEOF_VOIDP ${ptrSize} - #define SIZEOF_LONG_LONG 8 - EOF - - conda env create -f "${envFile}" || conda env update --prune -f "${envFile}" - conda activate invokeai - ''; - - version = "4.12.0"; - conda = { - aarch64-darwin = { - shell = conda-shell { - inherit shellHook installPath; - url = "https://repo.anaconda.com/miniconda/Miniconda3-py39_${version}-MacOSX-arm64.sh"; - sha256 = "4bd112168cc33f8a4a60d3ef7e72b52a85972d588cd065be803eb21d73b625ef"; - packages = [ frameworks.Security ] ++ packages; - }; - }; - x86_64-linux = { - shell = conda-shell { - inherit shellHook installPath; - url = "https://repo.continuum.io/miniconda/Miniconda3-py39_${version}-Linux-x86_64.sh"; - sha256 = "78f39f9bae971ec1ae7969f0516017f2413f17796670f7040725dd83fcff5689"; - packages = with pkgs; [ libGL glib ] ++ packages; - }; - }; - }; -in conda.${stdenv.system}.shell diff --git a/tests/test_config.py b/tests/test_config.py index 5d3dc46aa4..721edce487 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -84,6 +84,21 @@ def test_env_override(): assert conf.max_cache_size == 20 +def test_root_resists_cwd(): + previous = os.environ["INVOKEAI_ROOT"] + cwd = Path(os.getcwd()).resolve() + + os.environ["INVOKEAI_ROOT"] = "." + conf = InvokeAIAppConfig.get_config() + conf.parse_args([]) + assert conf.root_path == cwd + + os.chdir("..") + assert conf.root_path == cwd + os.environ["INVOKEAI_ROOT"] = previous + os.chdir(cwd) + + def test_type_coercion(): conf = InvokeAIAppConfig().get_config() conf.parse_args(argv=["--root=/tmp/foobar"])