mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[platform] revising startup-time system directory tests
- dropping obsolete file lock test - postponing the no-exec test as it is not critical (IDEA-331084) GitOrigin-RevId: e304fae08f82dedb896d24836869a3a3dd7bee15
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b229aa0d48
commit
acddd1bba5
@@ -926,6 +926,7 @@ shell.env.loading.failed={0} has failed to load the environment from ''{1}''. \
|
||||
Integration with tools that rely on environment variables may work incorrectly.
|
||||
shell.env.loading.learn.more=Learn more
|
||||
|
||||
temp.dir.exec.failed=The IDE cannot execute a test script in the temporary directory ''{0}''. Some things may work incorrectly.
|
||||
temp.dir.env.invalid=Environment variable ''{0}'' points to a non-existing directory (''{1}''). Some things may work incorrectly.
|
||||
|
||||
unsupported.windows=This version of Windows is no longer supported. Some features may not work correctly. Please use Windows 10 1809 or newer.
|
||||
|
||||
@@ -51,13 +51,10 @@ import java.io.IOException
|
||||
import java.lang.invoke.MethodHandles
|
||||
import java.lang.invoke.MethodType
|
||||
import java.lang.management.ManagementFactory
|
||||
import java.nio.channels.FileChannel
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.InvalidPathException
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardOpenOption
|
||||
import java.nio.file.attribute.PosixFileAttributeView
|
||||
import java.nio.file.attribute.PosixFilePermission
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.*
|
||||
@@ -69,6 +66,7 @@ import java.util.logging.ConsoleHandler
|
||||
import java.util.logging.Level
|
||||
import javax.swing.*
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
internal const val IDE_STARTED: String = "------------------------------------------------------ IDE STARTED ------------------------------------------------------"
|
||||
@@ -491,48 +489,22 @@ private suspend fun doCheckSystemDirs(configPath: Path, systemPath: Path): Boole
|
||||
|
||||
listOf(
|
||||
async {
|
||||
checkDirectory(directory = configPath,
|
||||
kind = "Config",
|
||||
property = PathManager.PROPERTY_CONFIG_PATH,
|
||||
checkWrite = true,
|
||||
checkLock = true,
|
||||
checkExec = false)
|
||||
checkDirectory(configPath, kind = "Config", property = PathManager.PROPERTY_CONFIG_PATH, checkWrite = true)
|
||||
},
|
||||
async {
|
||||
checkDirectory(directory = systemPath,
|
||||
kind = "System",
|
||||
property = PathManager.PROPERTY_SYSTEM_PATH,
|
||||
checkWrite = true,
|
||||
checkLock = true,
|
||||
checkExec = false)
|
||||
checkDirectory(systemPath, kind = "System", property = PathManager.PROPERTY_SYSTEM_PATH, checkWrite = true)
|
||||
},
|
||||
async {
|
||||
checkDirectory(directory = logPath,
|
||||
kind = "Log",
|
||||
property = PathManager.PROPERTY_LOG_PATH,
|
||||
checkWrite = !logPath.startsWith(systemPath),
|
||||
checkLock = false,
|
||||
checkExec = false)
|
||||
checkDirectory(logPath, kind = "Log", property = PathManager.PROPERTY_LOG_PATH, checkWrite = true)
|
||||
},
|
||||
async {
|
||||
checkDirectory(directory = tempPath,
|
||||
kind = "Temp",
|
||||
property = PathManager.PROPERTY_SYSTEM_PATH,
|
||||
checkWrite = !tempPath.startsWith(systemPath),
|
||||
checkLock = false,
|
||||
checkExec = SystemInfoRt.isUnix && !SystemInfoRt.isMac)
|
||||
|
||||
checkDirectory(tempPath, kind = "Temp", property = PathManager.PROPERTY_SYSTEM_PATH, checkWrite = !tempPath.startsWith(systemPath))
|
||||
}
|
||||
).awaitAll().all { it }
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkDirectory(directory: Path,
|
||||
kind: String,
|
||||
property: String,
|
||||
checkWrite: Boolean,
|
||||
checkLock: Boolean,
|
||||
checkExec: Boolean): Boolean {
|
||||
private fun checkDirectory(directory: Path, kind: String, property: String, checkWrite: Boolean): Boolean {
|
||||
var problem = "bootstrap.error.message.check.ide.directory.problem.cannot.create.the.directory"
|
||||
var reason = "bootstrap.error.message.check.ide.directory.possible.reason.path.is.incorrect"
|
||||
var tempFile: Path? = null
|
||||
@@ -542,33 +514,11 @@ private fun checkDirectory(directory: Path,
|
||||
reason = "bootstrap.error.message.check.ide.directory.possible.reason.directory.is.read.only.or.the.user.lacks.necessary.permissions"
|
||||
Files.createDirectories(directory)
|
||||
}
|
||||
|
||||
if (checkWrite || checkLock || checkExec) {
|
||||
if (checkWrite) {
|
||||
problem = "bootstrap.error.message.check.ide.directory.problem.the.ide.cannot.create.a.temporary.file.in.the.directory"
|
||||
reason = "bootstrap.error.message.check.ide.directory.possible.reason.directory.is.read.only.or.the.user.lacks.necessary.permissions"
|
||||
tempFile = directory.resolve("ij${Random().nextInt(Int.MAX_VALUE)}.tmp")
|
||||
Files.writeString(tempFile, "#!/bin/sh\nexit 0", StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
||||
if (checkLock) {
|
||||
problem = "bootstrap.error.message.check.ide.directory.problem.the.ide.cannot.create.a.lock.in.directory"
|
||||
reason = "bootstrap.error.message.check.ide.directory.possible.reason.the.directory.is.located.on.a.network.disk"
|
||||
FileChannel.open(tempFile, EnumSet.of(StandardOpenOption.WRITE)).use { channel ->
|
||||
channel.tryLock().use { lock ->
|
||||
if (lock == null) {
|
||||
throw IOException("File is locked")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (checkExec) {
|
||||
problem = "bootstrap.error.message.check.ide.directory.problem.the.ide.cannot.execute.test.script"
|
||||
reason = "bootstrap.error.message.check.ide.directory.possible.reason.partition.is.mounted.with.no.exec.option"
|
||||
Files.getFileAttributeView(tempFile!!, PosixFileAttributeView::class.java)
|
||||
.setPermissions(EnumSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE))
|
||||
val exitCode = ProcessBuilder(tempFile.toAbsolutePath().toString()).start().waitFor()
|
||||
if (exitCode != 0) {
|
||||
throw IOException("Unexpected exit value: $exitCode")
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
import com.intellij.openapi.util.io.NioFiles
|
||||
import com.intellij.platform.ide.CoreUiCoroutineScopeHolder
|
||||
import com.intellij.platform.ide.customization.ExternalProductResourceUrls
|
||||
import com.intellij.util.SystemProperties
|
||||
@@ -45,6 +46,7 @@ import java.nio.file.FileStore
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.InvalidPathException
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.system.exitProcess
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
@@ -61,6 +63,7 @@ internal suspend fun startSystemHealthMonitor() {
|
||||
checkEnvironment()
|
||||
withContext(Dispatchers.IO) {
|
||||
checkSignalBlocking()
|
||||
checkTempDirSanity()
|
||||
checkTempDirEnvVars()
|
||||
checkAncientOs()
|
||||
}
|
||||
@@ -280,6 +283,21 @@ private fun checkSignalBlocking() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkTempDirSanity() {
|
||||
if (SystemInfoRt.isUnix && !SystemInfoRt.isMac) {
|
||||
try {
|
||||
val probe = Files.createTempFile(Path.of(PathManager.getTempPath()), "ij-exec-check-", ".sh")
|
||||
NioFiles.setExecutable(probe)
|
||||
val process = ProcessBuilder(probe.toString()).start()
|
||||
if (!process.waitFor(1, TimeUnit.MINUTES)) throw IOException("${probe} timed out")
|
||||
if (process.exitValue() != 0) throw IOException("${probe} returned ${process.exitValue()}")
|
||||
}
|
||||
catch (e: Exception) {
|
||||
showNotification("temp.dir.exec.failed", suppressable = false, action = null, shorten(PathManager.getTempPath()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkTempDirEnvVars() {
|
||||
val envVars = if (SystemInfoRt.isWindows) sequenceOf("TMP", "TEMP") else sequenceOf("TMPDIR")
|
||||
for (name in envVars) {
|
||||
@@ -297,7 +315,7 @@ private fun checkTempDirEnvVars() {
|
||||
}
|
||||
|
||||
private fun checkAncientOs() {
|
||||
if (SystemInfo.isWindows) {
|
||||
if (SystemInfoRt.isWindows) {
|
||||
val buildNumber = SystemInfo.getWinBuildNumber()
|
||||
if (buildNumber != null && buildNumber < 10000) { // 10 1507 = 10240, Server 2016 = 14393
|
||||
showNotification("unsupported.windows", suppressable = true, null)
|
||||
|
||||
@@ -31,13 +31,9 @@ bootstrap.error.title.configuration.wizard.failed=Configuration Wizard Failed
|
||||
|
||||
bootstrap.error.message.check.ide.directory.problem.cannot.create.the.directory=The IDE cannot create the directory.
|
||||
bootstrap.error.message.check.ide.directory.problem.the.ide.cannot.create.a.temporary.file.in.the.directory=The IDE cannot create a temporary file in the directory.
|
||||
bootstrap.error.message.check.ide.directory.problem.the.ide.cannot.create.a.lock.in.directory=The IDE cannot create a lock file in the directory.
|
||||
bootstrap.error.message.check.ide.directory.problem.the.ide.cannot.execute.test.script=The IDE cannot execute a test script in the directory.
|
||||
|
||||
bootstrap.error.message.check.ide.directory.possible.reason.path.is.incorrect=Possible reason: path is incorrect.
|
||||
bootstrap.error.message.check.ide.directory.possible.reason.directory.is.read.only.or.the.user.lacks.necessary.permissions=Possible reason: parent directory is read-only or the user lacks necessary permissions.
|
||||
bootstrap.error.message.check.ide.directory.possible.reason.the.directory.is.located.on.a.network.disk=Possible reason: the directory is located on a network disk.
|
||||
bootstrap.error.message.check.ide.directory.possible.reason.partition.is.mounted.with.no.exec.option=Possible reason: the partition is mounted with 'no exec' option.
|
||||
|
||||
bootstrap.error.title.jetbrains.marketplace.boot.failure=JetBrains Marketplace Boot Failure
|
||||
|
||||
|
||||
Reference in New Issue
Block a user