|
1 | 1 | /*
|
2 | 2 | * Copyright 2011-2012 the original author or authors.
|
3 |
| - * |
| 3 | + * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
6 | 6 | * You may obtain a copy of the License at
|
7 |
| - * |
| 7 | + * |
8 | 8 | * http://www.apache.org/licenses/LICENSE-2.0
|
9 |
| - * |
| 9 | + * |
10 | 10 | * Unless required by applicable law or agreed to in writing, software
|
11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
12 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16 | 16 | package com.avast.server.hdfsshell.ui;
|
17 | 17 |
|
18 | 18 | import com.avast.server.hdfsshell.commands.ContextCommands;
|
| 19 | +import org.apache.commons.lang3.StringUtils; |
| 20 | +import org.slf4j.Logger; |
| 21 | +import org.slf4j.LoggerFactory; |
19 | 22 | import org.springframework.beans.factory.annotation.Autowired;
|
20 |
| -import org.springframework.boot.ansi.AnsiColor; |
21 |
| -import org.springframework.boot.ansi.AnsiOutput; |
22 | 23 | import org.springframework.core.Ordered;
|
23 | 24 | import org.springframework.core.annotation.Order;
|
24 | 25 | import org.springframework.shell.core.AbstractShell;
|
25 | 26 | import org.springframework.shell.plugin.support.DefaultPromptProvider;
|
26 | 27 | import org.springframework.stereotype.Component;
|
27 | 28 |
|
| 29 | +import javax.annotation.PostConstruct; |
| 30 | +import java.io.IOException; |
| 31 | +import java.util.Arrays; |
| 32 | +import java.util.Locale; |
| 33 | +import java.util.Set; |
| 34 | +import java.util.stream.Collectors; |
| 35 | + |
28 | 36 | /**
|
29 |
| - * @author Jarred Li |
| 37 | + * @author Vitasek L. |
30 | 38 | */
|
31 | 39 | @Component
|
32 | 40 | @Order(Ordered.HIGHEST_PRECEDENCE)
|
33 | 41 | public class ShellPromptProvider extends DefaultPromptProvider {
|
34 | 42 |
|
| 43 | + private static final Logger logger = LoggerFactory.getLogger(ShellPromptProvider.class); |
| 44 | + |
| 45 | + private static final String DEFAULT_PROMPT = "\033[36m\\u@\\h \033[0;39m\033[33m\\w\033[0;39m\033[36m\\$ \033[37;0;39m"; |
35 | 46 | final ContextCommands contextCommands;
|
36 | 47 |
|
| 48 | + private SimpleBashPromptInterpreter simpleBashPromptInterpreter; |
| 49 | + |
37 | 50 | @Autowired
|
38 | 51 | public ShellPromptProvider(ContextCommands contextCommands) {
|
39 | 52 | this.contextCommands = contextCommands;
|
40 | 53 | }
|
41 | 54 |
|
| 55 | + @PostConstruct |
| 56 | + public void init() { |
| 57 | + setPs1(System.getenv().getOrDefault("HDFS_SHELL_PROMPT", DEFAULT_PROMPT)); |
| 58 | + } |
| 59 | + |
| 60 | + public void setPs1(String ps1) { |
| 61 | + simpleBashPromptInterpreter = new SimpleBashPromptInterpreter.Builder(ps1). |
| 62 | + setAppName(() -> "hdfs-shell").setAppVersion(ShellBannerProvider::versionInfo). |
| 63 | + setLocale(Locale.ENGLISH). |
| 64 | + setUsername(this::getWhoami). |
| 65 | + setIsRoot(this::isRootPrompt). |
| 66 | + setCwdAbsolut(contextCommands::getCurrentDir). |
| 67 | + setCwdShort(this::getShortCwd). |
| 68 | + build(); |
| 69 | + } |
| 70 | + |
| 71 | + private boolean isRootPrompt() { |
| 72 | + final String whoami = this.getWhoami(); |
| 73 | + final String[] groupsForUser = contextCommands.getGroupsForUser(whoami); |
| 74 | + if (groupsForUser.length == 0) { //make guess |
| 75 | + return "root".equals(whoami) || "hdfs".equals(whoami); |
| 76 | + } |
| 77 | + final String[] groups = contextCommands.getConfiguration().get("dfs.permissions.superusergroup", "supergroup").split(","); |
| 78 | + final Set<String> adminGroups = Arrays.stream(groups).map(String::trim).collect(Collectors.toSet()); |
| 79 | + adminGroups.add("Administrators");//for Windows |
| 80 | + adminGroups.add("hdfs");//special cases |
| 81 | + adminGroups.add("root"); |
| 82 | + return Arrays.stream(groupsForUser).anyMatch(adminGroups::contains); |
| 83 | + } |
42 | 84 |
|
43 | 85 | @Override
|
44 | 86 | public String getPrompt() {
|
45 |
| - return AbstractShell.shellPrompt = |
46 |
| - AnsiOutput.toString(AnsiColor.CYAN, "hdfs-shell ") + |
47 |
| - AnsiOutput.toString(AnsiColor.YELLOW, contextCommands.getCurrentDir()) + |
48 |
| - AnsiOutput.toString(AnsiColor.CYAN, " >", AnsiColor.WHITE); |
| 87 | + return AbstractShell.shellPrompt = simpleBashPromptInterpreter.interpret(); |
| 88 | + } |
| 89 | + |
| 90 | + private String getWhoami() { |
| 91 | + try { |
| 92 | + return contextCommands.whoami(); |
| 93 | + } catch (IOException e) { |
| 94 | + logger.error("Failed to get active user", e); |
| 95 | + return "hdfs-shell"; |
| 96 | + } |
49 | 97 | }
|
50 | 98 |
|
| 99 | +// private String defaultPrompt() { |
| 100 | +// return AnsiOutput.toString(AnsiColor.CYAN, "hdfs-shell ") + |
| 101 | +// AnsiOutput.toString(AnsiColor.YELLOW, contextCommands.getCurrentDir()) + |
| 102 | +// AnsiOutput.toString(AnsiColor.CYAN, " >", AnsiColor.WHITE); |
| 103 | +// } |
| 104 | + |
51 | 105 |
|
52 | 106 | @Override
|
53 | 107 | public String getProviderName() {
|
54 | 108 | return "Hdfs-shell prompt";
|
55 | 109 | }
|
56 | 110 |
|
| 111 | + private String getShortCwd() { |
| 112 | + String currentDir = contextCommands.getCurrentDir(); |
| 113 | + if (currentDir.startsWith("/user/")) { |
| 114 | + final String userHome = "/user/" + this.getWhoami();//call getWhoami later |
| 115 | + if (currentDir.startsWith(userHome)) { |
| 116 | + currentDir = StringUtils.replaceOnce(currentDir, userHome, "~"); |
| 117 | + } |
| 118 | + } |
| 119 | + return currentDir; |
| 120 | + } |
57 | 121 | }
|
0 commit comments