You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by mo...@apache.org on 2022/02/10 06:52:52 UTC

[incubator-doris-manager] branch master created (now b82a5ed)

This is an automated email from the ASF dual-hosted git repository.

morningman pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git.


      at b82a5ed  [init] init commit

This branch includes the following new commits:

     new b82a5ed  [init] init commit

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: Re: Re: Re: [incubator-doris-manager] 01/01: [init] init commit

Posted by Willem Jiang <wi...@gmail.com>.
Just found a way to keep multiple sub directories here.
https://stackoverflow.com/questions/2982055/detach-many-subdirectories-into-a-new-separate-git-repository

Willem Jiang

Twitter: willemjiang
Weibo: 姜宁willem

On Fri, Feb 11, 2022 at 3:19 PM 陈明雨 <mo...@163.com> wrote:
>
> Actually they do share some interfeces and thrift definition.
> If these interfaces change, we need to update both connectors.
> So I suggest to put them in same repo, for easy developing.
>
>
>
>
> --
>
> 此致!Best Regards
> 陈明雨 Mingyu Chen
>
> Email:
> chenmingyu@apache.org
>
>
>
>
>
> 在 2022-02-11 15:05:17,"Willem Jiang" <wi...@gmail.com> 写道:
> >How about separating these two connectors into two repos, if these
> >connectors don't share anything in common.
> >
> >Willem Jiang
> >
> >Twitter: willemjiang
> >Weibo: 姜宁willem
> >
> >On Fri, Feb 11, 2022 at 11:25 AM 陈明雨 <mo...@163.com> wrote:
> >>
> >> I tried this way.
> >> But what we need is to merge the 2 subdirs:
> >> "extension/flink-doris-connector" and "extension/spark-doris-connector",
> >> into a new repository.
> >> This does not seem to be possible with this approach.
> >>
> >>
> >>
> >>
> >>
> >> --
> >>
> >> 此致!Best Regards
> >> 陈明雨 Mingyu Chen
> >>
> >> Email:
> >> chenmingyu@apache.org
> >>
> >>
> >>
> >>
> >>
> >> 在 2022-02-10 23:16:21,"Willem Jiang" <wi...@gmail.com> 写道:
> >> >Not sure if this link[1] can help you.
> >> >[1] https://ao.ms/how-to-split-a-subdirectory-to-a-new-git-repository-and-keep-the-history/
> >> >
> >> >Willem Jiang
> >> >
> >> >Twitter: willemjiang
> >> >Weibo: 姜宁willem
> >> >
> >> >On Thu, Feb 10, 2022 at 10:31 PM 陈明雨 <mo...@163.com> wrote:
> >> >>
> >> >> >Can we keep the commit history of the old code?
> >> >> >It's not a best practice to commit so big code here.
> >> >>
> >> >> Sorry I don't know how to keep the commit history of the connector's code separately, it's mixed with the commits of Doris' main code.
> >> >> If I merge the all commit history of the Doris' main code into this new repository, the repository will become as large as the trunk code base.
> >> >>
> >> >> --
> >> >>
> >> >> 此致!Best Regards
> >> >> 陈明雨 Mingyu Chen
> >> >>
> >> >> Email:
> >> >> chenmingyu@apache.org
> >> >>
> >> >>
> >> >>
> >> >>
> >> >>
> >> >> At 2022-02-10 21:21:38, "Willem Jiang" <wi...@gmail.com> wrote:
> >> >> >Can we keep the commit history of the old code?
> >> >> >It's not a best practice to commit so big code here.
> >> >> >
> >> >> >
> >> >> >On Thu, Feb 10, 2022 at 2:52 PM <mo...@apache.org> wrote:
> >> >> >>
> >> >> >> This is an automated email from the ASF dual-hosted git repository.
> >> >> >>
> >> >> >> morningman pushed a commit to branch master
> >> >> >> in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git
> >> >> >>
> >> >> >> commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
> >> >> >> Author: morningman <ch...@baidu.com>
> >> >> >> AuthorDate: Thu Feb 10 14:43:40 2022 +0800
> >> >> >>
> >> >> >>     [init] init commit
> >> >> >>
> >> >> >>     Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
> >> >> >> ---
> >> >> >>  .asf.yaml                                          |   40 +
> >> >> >>  .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
> >> >> >>  .github/ISSUE_TEMPLATE/config.yml                  |   23 +
> >> >> >>  .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
> >> >> >>  .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
> >> >> >>  .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
> >> >> >>  .github/workflows/approve-label-trigger.yml        |   28 +
> >> >> >>  .github/workflows/approve-label.yml                |   67 ++
> >> >> >>  .github/workflows/build-extension.yml              |   49 +
> >> >> >>  .github/workflows/license-eyes.yml                 |   35 +
> >> >> >>  .gitignore                                         |    7 +
> >> >> >>  .licenserc.yaml                                    |   36 +
> >> >> >
> >> >> >---------------------------------------------------------------------
> >> >> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
> >> >> >For additional commands, e-mail: dev-help@doris.apache.org
> >> >
> >> >---------------------------------------------------------------------
> >> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
> >> >For additional commands, e-mail: dev-help@doris.apache.org
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
> >For additional commands, e-mail: dev-help@doris.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
For additional commands, e-mail: dev-help@doris.apache.org


Re:Re: Re: Re: [incubator-doris-manager] 01/01: [init] init commit

Posted by 陈明雨 <mo...@163.com>.
Actually they do share some interfeces and thrift definition.
If these interfaces change, we need to update both connectors.
So I suggest to put them in same repo, for easy developing.




--

此致!Best Regards
陈明雨 Mingyu Chen

Email:
chenmingyu@apache.org





在 2022-02-11 15:05:17,"Willem Jiang" <wi...@gmail.com> 写道:
>How about separating these two connectors into two repos, if these
>connectors don't share anything in common.
>
>Willem Jiang
>
>Twitter: willemjiang
>Weibo: 姜宁willem
>
>On Fri, Feb 11, 2022 at 11:25 AM 陈明雨 <mo...@163.com> wrote:
>>
>> I tried this way.
>> But what we need is to merge the 2 subdirs:
>> "extension/flink-doris-connector" and "extension/spark-doris-connector",
>> into a new repository.
>> This does not seem to be possible with this approach.
>>
>>
>>
>>
>>
>> --
>>
>> 此致!Best Regards
>> 陈明雨 Mingyu Chen
>>
>> Email:
>> chenmingyu@apache.org
>>
>>
>>
>>
>>
>> 在 2022-02-10 23:16:21,"Willem Jiang" <wi...@gmail.com> 写道:
>> >Not sure if this link[1] can help you.
>> >[1] https://ao.ms/how-to-split-a-subdirectory-to-a-new-git-repository-and-keep-the-history/
>> >
>> >Willem Jiang
>> >
>> >Twitter: willemjiang
>> >Weibo: 姜宁willem
>> >
>> >On Thu, Feb 10, 2022 at 10:31 PM 陈明雨 <mo...@163.com> wrote:
>> >>
>> >> >Can we keep the commit history of the old code?
>> >> >It's not a best practice to commit so big code here.
>> >>
>> >> Sorry I don't know how to keep the commit history of the connector's code separately, it's mixed with the commits of Doris' main code.
>> >> If I merge the all commit history of the Doris' main code into this new repository, the repository will become as large as the trunk code base.
>> >>
>> >> --
>> >>
>> >> 此致!Best Regards
>> >> 陈明雨 Mingyu Chen
>> >>
>> >> Email:
>> >> chenmingyu@apache.org
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> At 2022-02-10 21:21:38, "Willem Jiang" <wi...@gmail.com> wrote:
>> >> >Can we keep the commit history of the old code?
>> >> >It's not a best practice to commit so big code here.
>> >> >
>> >> >
>> >> >On Thu, Feb 10, 2022 at 2:52 PM <mo...@apache.org> wrote:
>> >> >>
>> >> >> This is an automated email from the ASF dual-hosted git repository.
>> >> >>
>> >> >> morningman pushed a commit to branch master
>> >> >> in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git
>> >> >>
>> >> >> commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
>> >> >> Author: morningman <ch...@baidu.com>
>> >> >> AuthorDate: Thu Feb 10 14:43:40 2022 +0800
>> >> >>
>> >> >>     [init] init commit
>> >> >>
>> >> >>     Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
>> >> >> ---
>> >> >>  .asf.yaml                                          |   40 +
>> >> >>  .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
>> >> >>  .github/ISSUE_TEMPLATE/config.yml                  |   23 +
>> >> >>  .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
>> >> >>  .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
>> >> >>  .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
>> >> >>  .github/workflows/approve-label-trigger.yml        |   28 +
>> >> >>  .github/workflows/approve-label.yml                |   67 ++
>> >> >>  .github/workflows/build-extension.yml              |   49 +
>> >> >>  .github/workflows/license-eyes.yml                 |   35 +
>> >> >>  .gitignore                                         |    7 +
>> >> >>  .licenserc.yaml                                    |   36 +
>> >> >
>> >> >---------------------------------------------------------------------
>> >> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
>> >> >For additional commands, e-mail: dev-help@doris.apache.org
>> >
>> >---------------------------------------------------------------------
>> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
>> >For additional commands, e-mail: dev-help@doris.apache.org
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
>For additional commands, e-mail: dev-help@doris.apache.org

Re: Re: Re: [incubator-doris-manager] 01/01: [init] init commit

Posted by Willem Jiang <wi...@gmail.com>.
How about separating these two connectors into two repos, if these
connectors don't share anything in common.

Willem Jiang

Twitter: willemjiang
Weibo: 姜宁willem

On Fri, Feb 11, 2022 at 11:25 AM 陈明雨 <mo...@163.com> wrote:
>
> I tried this way.
> But what we need is to merge the 2 subdirs:
> "extension/flink-doris-connector" and "extension/spark-doris-connector",
> into a new repository.
> This does not seem to be possible with this approach.
>
>
>
>
>
> --
>
> 此致!Best Regards
> 陈明雨 Mingyu Chen
>
> Email:
> chenmingyu@apache.org
>
>
>
>
>
> 在 2022-02-10 23:16:21,"Willem Jiang" <wi...@gmail.com> 写道:
> >Not sure if this link[1] can help you.
> >[1] https://ao.ms/how-to-split-a-subdirectory-to-a-new-git-repository-and-keep-the-history/
> >
> >Willem Jiang
> >
> >Twitter: willemjiang
> >Weibo: 姜宁willem
> >
> >On Thu, Feb 10, 2022 at 10:31 PM 陈明雨 <mo...@163.com> wrote:
> >>
> >> >Can we keep the commit history of the old code?
> >> >It's not a best practice to commit so big code here.
> >>
> >> Sorry I don't know how to keep the commit history of the connector's code separately, it's mixed with the commits of Doris' main code.
> >> If I merge the all commit history of the Doris' main code into this new repository, the repository will become as large as the trunk code base.
> >>
> >> --
> >>
> >> 此致!Best Regards
> >> 陈明雨 Mingyu Chen
> >>
> >> Email:
> >> chenmingyu@apache.org
> >>
> >>
> >>
> >>
> >>
> >> At 2022-02-10 21:21:38, "Willem Jiang" <wi...@gmail.com> wrote:
> >> >Can we keep the commit history of the old code?
> >> >It's not a best practice to commit so big code here.
> >> >
> >> >
> >> >On Thu, Feb 10, 2022 at 2:52 PM <mo...@apache.org> wrote:
> >> >>
> >> >> This is an automated email from the ASF dual-hosted git repository.
> >> >>
> >> >> morningman pushed a commit to branch master
> >> >> in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git
> >> >>
> >> >> commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
> >> >> Author: morningman <ch...@baidu.com>
> >> >> AuthorDate: Thu Feb 10 14:43:40 2022 +0800
> >> >>
> >> >>     [init] init commit
> >> >>
> >> >>     Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
> >> >> ---
> >> >>  .asf.yaml                                          |   40 +
> >> >>  .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
> >> >>  .github/ISSUE_TEMPLATE/config.yml                  |   23 +
> >> >>  .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
> >> >>  .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
> >> >>  .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
> >> >>  .github/workflows/approve-label-trigger.yml        |   28 +
> >> >>  .github/workflows/approve-label.yml                |   67 ++
> >> >>  .github/workflows/build-extension.yml              |   49 +
> >> >>  .github/workflows/license-eyes.yml                 |   35 +
> >> >>  .gitignore                                         |    7 +
> >> >>  .licenserc.yaml                                    |   36 +
> >> >
> >> >---------------------------------------------------------------------
> >> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
> >> >For additional commands, e-mail: dev-help@doris.apache.org
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
> >For additional commands, e-mail: dev-help@doris.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
For additional commands, e-mail: dev-help@doris.apache.org


Re:Re: Re: [incubator-doris-manager] 01/01: [init] init commit

Posted by 陈明雨 <mo...@163.com>.
I tried this way.
But what we need is to merge the 2 subdirs: 
"extension/flink-doris-connector" and "extension/spark-doris-connector",
into a new repository.
This does not seem to be possible with this approach.





--

此致!Best Regards
陈明雨 Mingyu Chen

Email:
chenmingyu@apache.org





在 2022-02-10 23:16:21,"Willem Jiang" <wi...@gmail.com> 写道:
>Not sure if this link[1] can help you.
>[1] https://ao.ms/how-to-split-a-subdirectory-to-a-new-git-repository-and-keep-the-history/
>
>Willem Jiang
>
>Twitter: willemjiang
>Weibo: 姜宁willem
>
>On Thu, Feb 10, 2022 at 10:31 PM 陈明雨 <mo...@163.com> wrote:
>>
>> >Can we keep the commit history of the old code?
>> >It's not a best practice to commit so big code here.
>>
>> Sorry I don't know how to keep the commit history of the connector's code separately, it's mixed with the commits of Doris' main code.
>> If I merge the all commit history of the Doris' main code into this new repository, the repository will become as large as the trunk code base.
>>
>> --
>>
>> 此致!Best Regards
>> 陈明雨 Mingyu Chen
>>
>> Email:
>> chenmingyu@apache.org
>>
>>
>>
>>
>>
>> At 2022-02-10 21:21:38, "Willem Jiang" <wi...@gmail.com> wrote:
>> >Can we keep the commit history of the old code?
>> >It's not a best practice to commit so big code here.
>> >
>> >
>> >On Thu, Feb 10, 2022 at 2:52 PM <mo...@apache.org> wrote:
>> >>
>> >> This is an automated email from the ASF dual-hosted git repository.
>> >>
>> >> morningman pushed a commit to branch master
>> >> in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git
>> >>
>> >> commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
>> >> Author: morningman <ch...@baidu.com>
>> >> AuthorDate: Thu Feb 10 14:43:40 2022 +0800
>> >>
>> >>     [init] init commit
>> >>
>> >>     Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
>> >> ---
>> >>  .asf.yaml                                          |   40 +
>> >>  .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
>> >>  .github/ISSUE_TEMPLATE/config.yml                  |   23 +
>> >>  .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
>> >>  .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
>> >>  .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
>> >>  .github/workflows/approve-label-trigger.yml        |   28 +
>> >>  .github/workflows/approve-label.yml                |   67 ++
>> >>  .github/workflows/build-extension.yml              |   49 +
>> >>  .github/workflows/license-eyes.yml                 |   35 +
>> >>  .gitignore                                         |    7 +
>> >>  .licenserc.yaml                                    |   36 +
>> >
>> >---------------------------------------------------------------------
>> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
>> >For additional commands, e-mail: dev-help@doris.apache.org
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
>For additional commands, e-mail: dev-help@doris.apache.org

Re: Re: [incubator-doris-manager] 01/01: [init] init commit

Posted by Willem Jiang <wi...@gmail.com>.
Not sure if this link[1] can help you.
[1] https://ao.ms/how-to-split-a-subdirectory-to-a-new-git-repository-and-keep-the-history/

Willem Jiang

Twitter: willemjiang
Weibo: 姜宁willem

On Thu, Feb 10, 2022 at 10:31 PM 陈明雨 <mo...@163.com> wrote:
>
> >Can we keep the commit history of the old code?
> >It's not a best practice to commit so big code here.
>
> Sorry I don't know how to keep the commit history of the connector's code separately, it's mixed with the commits of Doris' main code.
> If I merge the all commit history of the Doris' main code into this new repository, the repository will become as large as the trunk code base.
>
> --
>
> 此致!Best Regards
> 陈明雨 Mingyu Chen
>
> Email:
> chenmingyu@apache.org
>
>
>
>
>
> At 2022-02-10 21:21:38, "Willem Jiang" <wi...@gmail.com> wrote:
> >Can we keep the commit history of the old code?
> >It's not a best practice to commit so big code here.
> >
> >
> >On Thu, Feb 10, 2022 at 2:52 PM <mo...@apache.org> wrote:
> >>
> >> This is an automated email from the ASF dual-hosted git repository.
> >>
> >> morningman pushed a commit to branch master
> >> in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git
> >>
> >> commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
> >> Author: morningman <ch...@baidu.com>
> >> AuthorDate: Thu Feb 10 14:43:40 2022 +0800
> >>
> >>     [init] init commit
> >>
> >>     Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
> >> ---
> >>  .asf.yaml                                          |   40 +
> >>  .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
> >>  .github/ISSUE_TEMPLATE/config.yml                  |   23 +
> >>  .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
> >>  .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
> >>  .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
> >>  .github/workflows/approve-label-trigger.yml        |   28 +
> >>  .github/workflows/approve-label.yml                |   67 ++
> >>  .github/workflows/build-extension.yml              |   49 +
> >>  .github/workflows/license-eyes.yml                 |   35 +
> >>  .gitignore                                         |    7 +
> >>  .licenserc.yaml                                    |   36 +
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
> >For additional commands, e-mail: dev-help@doris.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
For additional commands, e-mail: dev-help@doris.apache.org


Re:Re: [incubator-doris-manager] 01/01: [init] init commit

Posted by 陈明雨 <mo...@163.com>.
>Can we keep the commit history of the old code?
>It's not a best practice to commit so big code here.

Sorry I don't know how to keep the commit history of the connector's code separately, it's mixed with the commits of Doris' main code.
If I merge the all commit history of the Doris' main code into this new repository, the repository will become as large as the trunk code base.

--

此致!Best Regards
陈明雨 Mingyu Chen

Email:
chenmingyu@apache.org





At 2022-02-10 21:21:38, "Willem Jiang" <wi...@gmail.com> wrote:
>Can we keep the commit history of the old code?
>It's not a best practice to commit so big code here.
>
>
>On Thu, Feb 10, 2022 at 2:52 PM <mo...@apache.org> wrote:
>>
>> This is an automated email from the ASF dual-hosted git repository.
>>
>> morningman pushed a commit to branch master
>> in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git
>>
>> commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
>> Author: morningman <ch...@baidu.com>
>> AuthorDate: Thu Feb 10 14:43:40 2022 +0800
>>
>>     [init] init commit
>>
>>     Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
>> ---
>>  .asf.yaml                                          |   40 +
>>  .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
>>  .github/ISSUE_TEMPLATE/config.yml                  |   23 +
>>  .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
>>  .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
>>  .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
>>  .github/workflows/approve-label-trigger.yml        |   28 +
>>  .github/workflows/approve-label.yml                |   67 ++
>>  .github/workflows/build-extension.yml              |   49 +
>>  .github/workflows/license-eyes.yml                 |   35 +
>>  .gitignore                                         |    7 +
>>  .licenserc.yaml                                    |   36 +
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
>For additional commands, e-mail: dev-help@doris.apache.org

Re: [incubator-doris-manager] 01/01: [init] init commit

Posted by Willem Jiang <wi...@gmail.com>.
Can we keep the commit history of the old code?
It's not a best practice to commit so big code here.


On Thu, Feb 10, 2022 at 2:52 PM <mo...@apache.org> wrote:
>
> This is an automated email from the ASF dual-hosted git repository.
>
> morningman pushed a commit to branch master
> in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git
>
> commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
> Author: morningman <ch...@baidu.com>
> AuthorDate: Thu Feb 10 14:43:40 2022 +0800
>
>     [init] init commit
>
>     Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
> ---
>  .asf.yaml                                          |   40 +
>  .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
>  .github/ISSUE_TEMPLATE/config.yml                  |   23 +
>  .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
>  .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
>  .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
>  .github/workflows/approve-label-trigger.yml        |   28 +
>  .github/workflows/approve-label.yml                |   67 ++
>  .github/workflows/build-extension.yml              |   49 +
>  .github/workflows/license-eyes.yml                 |   35 +
>  .gitignore                                         |    7 +
>  .licenserc.yaml                                    |   36 +

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@doris.apache.org
For additional commands, e-mail: dev-help@doris.apache.org


[incubator-doris-manager] 01/01: [init] init commit

Posted by mo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris-manager.git

commit b82a5edbcec201b1dcfe1c6937ffc9325a8f17a1
Author: morningman <ch...@baidu.com>
AuthorDate: Thu Feb 10 14:43:40 2022 +0800

    [init] init commit
    
    Move manager code from https://github.com/apache/incubator-doris/tree/doris-manager@4a22750
---
 .asf.yaml                                          |   40 +
 .github/ISSUE_TEMPLATE/bug_report.yml              |  109 ++
 .github/ISSUE_TEMPLATE/config.yml                  |   23 +
 .github/ISSUE_TEMPLATE/enhancement.yml             |   76 ++
 .github/ISSUE_TEMPLATE/feature-request.yml         |   78 ++
 .github/PULL_REQUEST_TEMPLATE.md                   |   19 +
 .github/workflows/approve-label-trigger.yml        |   28 +
 .github/workflows/approve-label.yml                |   67 ++
 .github/workflows/build-extension.yml              |   49 +
 .github/workflows/license-eyes.yml                 |   35 +
 .gitignore                                         |    7 +
 .licenserc.yaml                                    |   36 +
 CODE_OF_CONDUCT.md                                 |   95 ++
 CONTRIBUTING.md                                    |   24 +
 CONTRIBUTING_CN.md                                 |   24 +
 LICENSE.txt                                        |  202 ++++
 NOTICE.txt                                         |    5 +
 README.md                                          |   47 +
 manager/README.md                                  |  103 ++
 manager/build.sh                                   |   52 +
 manager/checkstyle/studio_checks.xml               |  299 +++++
 manager/checkstyle/suppressions.xml                |   23 +
 manager/conf/manager.conf                          |   57 +
 manager/dm-agent/pom.xml                           |   66 ++
 .../doris/manager/agent/DmAgentApplication.java    |  105 ++
 .../doris/manager/agent/api/CommandController.java |   58 +
 .../doris/manager/agent/api/CommonControllder.java |   87 ++
 .../manager/agent/api/HardwareInfoController.java  |   43 +
 .../doris/manager/agent/api/LogController.java     |  117 ++
 .../doris/manager/agent/command/BeCommand.java     |   35 +
 .../manager/agent/command/BeInstallCommand.java    |  112 ++
 .../manager/agent/command/BeStartCommand.java      |   65 ++
 .../doris/manager/agent/command/BeStopCommand.java |   51 +
 .../doris/manager/agent/command/BrokerCommand.java |   35 +
 .../agent/command/BrokerInstallCommand.java        |  103 ++
 .../manager/agent/command/BrokerStartCommand.java  |   66 ++
 .../manager/agent/command/BrokerStopCommand.java   |   51 +
 .../doris/manager/agent/command/Command.java       |   51 +
 .../manager/agent/command/CommandFactory.java      |  113 ++
 .../agent/command/CommandResultService.java        |  123 ++
 .../doris/manager/agent/command/ExpandCommand.java |   28 +
 .../doris/manager/agent/command/FeCommand.java     |   35 +
 .../manager/agent/command/FeInstallCommand.java    |  115 ++
 .../manager/agent/command/FeStartCommand.java      |   70 ++
 .../doris/manager/agent/command/FeStopCommand.java |   51 +
 .../manager/agent/command/WriteBeConfCommand.java  |  103 ++
 .../agent/command/WriteBrokerConfCommand.java      |   87 ++
 .../manager/agent/command/WriteFeConfCommand.java  |  103 ++
 .../doris/manager/agent/common/AgentConstants.java |   51 +
 .../doris/manager/agent/common/PropertiesUtil.java |   51 +
 .../manager/agent/exception/AgentException.java    |   42 +
 .../agent/exception/GlobalExceptionHandler.java    |   40 +
 .../doris/manager/agent/register/AgentContext.java |   91 ++
 .../manager/agent/register/AgentHeartbeat.java     |   66 ++
 .../manager/agent/register/ApplicationOption.java  |   28 +
 .../doris/manager/agent/service/BeService.java     |  146 +++
 .../doris/manager/agent/service/BrokerService.java |   70 ++
 .../doris/manager/agent/service/FeService.java     |  123 ++
 .../doris/manager/agent/service/Service.java       |  122 ++
 .../manager/agent/service/ServiceContext.java      |  114 ++
 .../manager/agent/task/AbsAsyncTaskHandler.java    |   41 +
 .../manager/agent/task/ITaskHandlerFactory.java    |   22 +
 .../org/apache/doris/manager/agent/task/LRU.java   |   56 +
 .../manager/agent/task/QueuedTaskHandler.java      |   27 +
 .../agent/task/QueuedTaskHandlerFactory.java       |   34 +
 .../doris/manager/agent/task/ScriptTask.java       |   63 ++
 .../doris/manager/agent/task/ScriptTaskDesc.java   |   30 +
 .../doris/manager/agent/task/SyncTaskHandler.java  |   26 +
 .../manager/agent/task/SyncTaskHandlerFactory.java |   34 +
 .../org/apache/doris/manager/agent/task/Task.java  |   85 ++
 .../doris/manager/agent/task/TaskContext.java      |   36 +
 .../apache/doris/manager/agent/task/TaskDesc.java  |   30 +
 .../manager/agent/task/TaskExecutorService.java    |   29 +
 .../doris/manager/agent/task/TaskHandler.java      |   29 +
 .../manager/agent/task/TaskHandlerFactory.java     |   46 +
 .../apache/doris/manager/agent/task/TaskHook.java  |   22 +
 .../apache/doris/manager/agent/util/Request.java   |  115 ++
 .../src/main/resources/application.properties      |    1 +
 .../dm-agent/src/main/resources/logback-spring.xml |   60 +
 manager/dm-common/pom.xml                          |   15 +
 .../manager/common/domain/AgentRoleRegister.java   |   62 +
 .../common/domain/BeInstallCommandRequestBody.java |   50 +
 .../common/domain/BeStartCommandRequestBody.java   |   30 +
 .../domain/BrokerInstallCommandRequestBody.java    |   40 +
 .../domain/BrokerStartCommandRequestBody.java      |   30 +
 .../manager/common/domain/CommandRequest.java      |   40 +
 .../doris/manager/common/domain/CommandResult.java |   34 +
 .../doris/manager/common/domain/CommandType.java   |   53 +
 .../common/domain/FeInstallCommandRequestBody.java |   48 +
 .../common/domain/FeStartCommandRequestBody.java   |   39 +
 .../doris/manager/common/domain/HardwareInfo.java  |   54 +
 .../doris/manager/common/domain/RResult.java       |   90 ++
 .../doris/manager/common/domain/ServiceRole.java   |   43 +
 .../doris/manager/common/domain/TaskResult.java    |   89 ++
 .../doris/manager/common/domain/TaskState.java     |   35 +
 .../domain/WriteBeConfCommandRequestBody.java      |   39 +
 .../domain/WriteBrokerConfCommandRequestBody.java  |   30 +
 .../domain/WriteFeConfCommandRequestBody.java      |   39 +
 manager/dm-server/pom.xml                          |   39 +
 .../org/apache/doris/stack/agent/AgentCache.java   |  104 ++
 .../doris/stack/agent/AgentHeatbeatRunner.java     |   83 ++
 .../org/apache/doris/stack/agent/AgentRest.java    |   98 ++
 .../doris/stack/agent/AgentTaskStatusRunner.java   |   68 ++
 .../doris/stack/bean/SpringApplicationContext.java |   46 +
 .../doris/stack/component/AgentComponent.java      |   87 ++
 .../doris/stack/component/AgentRoleComponent.java  |   66 ++
 .../stack/component/ProcessInstanceComponent.java  |   98 ++
 .../stack/component/TaskInstanceComponent.java     |  167 +++
 .../doris/stack/config/RestTemplateConfig.java     |   30 +
 .../apache/doris/stack/constants/AgentStatus.java  |   25 +
 .../apache/doris/stack/constants/CmdTypeEnum.java  |   32 +
 .../apache/doris/stack/constants/Constants.java    |   34 +
 .../doris/stack/constants/ExecutionStatus.java     |   88 ++
 .../org/apache/doris/stack/constants/Flag.java     |   53 +
 .../doris/stack/constants/ProcessTypeEnum.java     |   76 ++
 .../apache/doris/stack/constants/TaskTypeEnum.java |   81 ++
 .../doris/stack/controller/AgentController.java    |  133 +++
 .../stack/controller/ProcessTaskController.java    |  146 +++
 .../doris/stack/controller/ServerController.java   |  106 ++
 .../apache/doris/stack/dao/AgentRepository.java    |   37 +
 .../doris/stack/dao/AgentRoleRepository.java       |   40 +
 .../doris/stack/dao/ProcessInstanceRepository.java |   34 +
 .../doris/stack/dao/TaskInstanceRepository.java    |   42 +
 .../org/apache/doris/stack/entity/AgentEntity.java |   84 ++
 .../apache/doris/stack/entity/AgentRoleEntity.java |   69 ++
 .../doris/stack/entity/ProcessInstanceEntity.java  |  105 ++
 .../doris/stack/entity/TaskInstanceEntity.java     |  136 +++
 .../stack/exceptions/GlobalExceptionHandler.java   |   41 +
 .../doris/stack/exceptions/JdbcException.java      |   44 +
 .../doris/stack/exceptions/ServerException.java    |   44 +
 .../doris/stack/model/request/AgentCommon.java     |   32 +
 .../doris/stack/model/request/AgentInstallReq.java |   46 +
 .../doris/stack/model/request/AgentRegister.java   |   34 +
 .../doris/stack/model/request/BuildClusterReq.java |   39 +
 .../doris/stack/model/request/DeployConfigReq.java |   37 +
 .../doris/stack/model/request/DorisExecReq.java    |   38 +
 .../doris/stack/model/request/DorisInstallReq.java |   35 +
 .../doris/stack/model/request/DorisStartReq.java   |   35 +
 .../stack/model/response/CurrentProcessResp.java   |   49 +
 .../stack/model/response/TaskInstanceResp.java     |   64 ++
 .../doris/stack/model/task/AgentInstall.java       |   47 +
 .../org/apache/doris/stack/model/task/BeJoin.java  |   39 +
 .../doris/stack/model/task/DeployConfig.java       |   39 +
 .../doris/stack/model/task/DorisInstall.java       |   36 +
 .../apache/doris/stack/model/task/DorisStart.java  |   35 +
 .../apache/doris/stack/model/task/TaskDesc.java    |   24 +
 .../org/apache/doris/stack/runner/TaskContext.java |   40 +
 .../doris/stack/runner/TaskExecCallback.java       |   65 ++
 .../doris/stack/runner/TaskExecuteRunner.java      |   91 ++
 .../doris/stack/runner/TaskExecuteThread.java      |   76 ++
 .../apache/doris/stack/service/AgentProcess.java   |   61 +
 .../apache/doris/stack/service/ProcessTask.java    |   64 ++
 .../apache/doris/stack/service/ServerProcess.java  |   51 +
 .../doris/stack/service/impl/AgentProcessImpl.java |  736 ++++++++++++
 .../doris/stack/service/impl/ProcessTaskImpl.java  |  275 +++++
 .../stack/service/impl/ServerProcessImpl.java      |  186 +++
 .../org/apache/doris/stack/shell/BaseCommand.java  |   76 ++
 .../java/org/apache/doris/stack/shell/SCP.java     |   55 +
 .../java/org/apache/doris/stack/shell/SSH.java     |  107 ++
 .../org/apache/doris/stack/task/AbstractTask.java  |   46 +
 .../apache/doris/stack/task/InstallAgentTask.java  |  160 +++
 .../java/org/apache/doris/stack/util/JdbcUtil.java |   93 ++
 .../org/apache/doris/stack/util/TelnetUtil.java    |   42 +
 ...216\245\345\217\243\346\226\207\346\241\243.md" |  925 +++++++++++++++
 ...203\250\347\275\262\346\226\207\346\241\243.md" |   52 +
 manager/doris-manager/.babelrc                     |   42 +
 manager/doris-manager/.eslintrc.js                 |   34 +
 manager/doris-manager/.gitignore                   |   16 +
 manager/doris-manager/.prettierrc.js               |   30 +
 manager/doris-manager/README.md                    |   95 ++
 manager/doris-manager/babel.config.js              |   24 +
 .../doris-manager/config/webpack.base.config.js    |  160 +++
 manager/doris-manager/config/webpack.dev.config.js |   58 +
 .../doris-manager/config/webpack.prod.config.js    |   90 ++
 manager/doris-manager/package.json                 |   84 ++
 manager/doris-manager/postcss.config.js            |   41 +
 manager/doris-manager/public/index.html            |   29 +
 manager/doris-manager/public/locales/en-us.json    |  182 +++
 manager/doris-manager/public/locales/zh-cn.json    |  195 ++++
 manager/doris-manager/src/app.tsx                  |   27 +
 manager/doris-manager/src/assets/404.png           |  Bin 0 -> 9247 bytes
 manager/doris-manager/src/assets/background.jpg    |  Bin 0 -> 118647 bytes
 manager/doris-manager/src/assets/logo.png          |  Bin 0 -> 58139 bytes
 manager/doris-manager/src/assets/logo_nav.png      |  Bin 0 -> 45807 bytes
 manager/doris-manager/src/assets/manager_logo.png  |  Bin 0 -> 48528 bytes
 manager/doris-manager/src/common/common.api.ts     |    9 +
 manager/doris-manager/src/common/common.context.ts |    4 +
 manager/doris-manager/src/common/common.data.ts    |   96 ++
 .../doris-manager/src/common/common.interface.ts   |   22 +
 .../src/components/clipped-text/clipped-text.tsx   |   72 ++
 .../src/components/common-header/header.api.ts     |   28 +
 .../components/common-header/header.interface.ts   |   23 +
 .../components/common-header/header.module.less    |   48 +
 .../src/components/common-header/header.tsx        |   61 +
 .../src/components/copy-text/index.less            |   34 +
 .../src/components/copy-text/index.tsx             |   44 +
 .../src/components/doris-modal/doris-modal.jsx     |   41 +
 .../src/components/header/header.api.ts            |   37 +
 .../doris-manager/src/components/header/header.tsx |  104 ++
 .../src/components/header/index.module.less        |   60 +
 .../src/components/helper/helper.less              |   23 +
 .../doris-manager/src/components/helper/helper.tsx |   30 +
 .../doris-manager/src/components/loading/index.tsx |   30 +
 .../src/components/loading/loading.less            |   30 +
 .../components/loadingwrapper/loadingwrapper.tsx   |   41 +
 .../src/components/metadata/index.tsx              |  128 +++
 .../src/components/not-found/index.tsx             |   27 +
 .../src/components/sidebar/sidebar.less            |   24 +
 .../src/components/sidebar/sidebar.tsx             |   88 ++
 .../src/components/sidebar/siderbar.data.ts        |    0
 manager/doris-manager/src/config.ts                |   28 +
 manager/doris-manager/src/hooks/use-pagination.ts  |   47 +
 manager/doris-manager/src/i18n.tsx                 |   47 +
 manager/doris-manager/src/index.css                |   35 +
 manager/doris-manager/src/index.tsx                |   25 +
 .../doris-manager/src/interfaces/http.interface.ts |   22 +
 .../doris-manager/src/layout/page-side/index.tsx   |   51 +
 .../src/layout/page-side/page-side.module.less     |   27 +
 manager/doris-manager/src/routes.tsx               |   57 +
 .../doris-manager/src/routes/cluster/cluster.tsx   |   16 +
 .../doris-manager/src/routes/cluster/list/list.tsx |    0
 .../src/routes/cluster/monitor/monitor.api.ts      |   70 ++
 .../src/routes/cluster/monitor/monitor.data.ts     |  111 ++
 .../src/routes/cluster/monitor/monitor.less        |   24 +
 .../src/routes/cluster/monitor/monitor.tsx         |  438 +++++++
 manager/doris-manager/src/routes/container.less    |   24 +
 manager/doris-manager/src/routes/container.tsx     |   89 ++
 .../dashboard/components/dashboard-item/index.tsx  |   37 +
 .../dashboard-item/message-item.interface.ts       |   23 +
 .../components/dashboard-item/message-item.less    |   57 +
 .../dashboard/connect-info/connect-info.less       |   23 +
 .../routes/dashboard/connect-info/connect-info.tsx |   68 ++
 .../src/routes/dashboard/dashboard.api.ts          |   31 +
 .../src/routes/dashboard/dashboard.data.ts         |   21 +
 .../src/routes/dashboard/dashboard.interface.ts    |   33 +
 .../src/routes/dashboard/dashboard.less            |   27 +
 .../src/routes/dashboard/dashboard.tsx             |   75 ++
 .../src/routes/dashboard/overview/overview.less    |   23 +
 .../src/routes/dashboard/overview/overview.tsx     |   69 ++
 .../src/routes/database/database.api.ts            |   29 +
 .../src/routes/database/database.interface.ts      |   28 +
 .../src/routes/database/database.module.less       |   42 +
 .../doris-manager/src/routes/database/index.tsx    |   91 ++
 manager/doris-manager/src/routes/meta/meta.less    |   42 +
 manager/doris-manager/src/routes/meta/meta.tsx     |   52 +
 .../src/routes/node/dashboard/index.module.less    |   20 +
 .../src/routes/node/dashboard/index.tsx            |  336 ++++++
 .../src/routes/node/dashboard/monitor.api.ts       |   61 +
 .../src/routes/node/dashboard/monitor.data.ts      |   96 ++
 .../src/routes/node/dashboard/monitor.less         |   24 +
 .../node/list/be-configuration/be-config.api.ts    |   37 +
 .../routes/node/list/be-configuration/index.tsx    |  537 +++++++++
 .../src/routes/node/list/config.data.ts            |   26 +
 .../src/routes/node/list/configuration/index.tsx   |  108 ++
 .../node/list/fe-configuration/fe-config.api.ts    |   37 +
 .../routes/node/list/fe-configuration/index.tsx    |  538 +++++++++
 .../doris-manager/src/routes/node/list/index.tsx   |  191 ++++
 .../doris-manager/src/routes/node/list/node.api.ts |   33 +
 .../src/routes/passport/forgot.login.tsx           |   37 +
 .../src/routes/passport/index.module.less          |   45 +
 .../doris-manager/src/routes/passport/index.tsx    |   94 ++
 .../src/routes/passport/passport.api.ts            |   30 +
 manager/doris-manager/src/routes/query/index.tsx   |  149 +++
 .../src/routes/query/query-details/code.css        |  126 +++
 .../src/routes/query/query-details/index.tsx       |  124 ++
 .../src/routes/query/query-details/profile.tsx     |   93 ++
 .../routes/query/query-details/query.module.less   |   56 +
 .../doris-manager/src/routes/query/query.api.ts    |   49 +
 .../doris-manager/src/routes/query/query.data.ts   |   28 +
 .../src/routes/super-admin-container.tsx           |   50 +
 .../super-admin/space/detail/space-detail.tsx      |  130 +++
 .../src/routes/super-admin/space/list/list.less    |    0
 .../src/routes/super-admin/space/list/list.tsx     |   80 ++
 .../super-admin/space/new-space/new-space.tsx      |  198 ++++
 .../src/routes/super-admin/space/space.api.ts      |   51 +
 .../routes/super-admin/space/space.interface.ts    |   36 +
 .../src/routes/super-admin/space/space.less        |  105 ++
 .../src/routes/table-content/index.tsx             |  114 ++
 .../src/routes/table-content/schema/schema.api.ts  |   26 +
 .../src/routes/table-content/schema/schema.data.ts |   80 ++
 .../src/routes/table-content/schema/schema.tsx     |   97 ++
 .../src/routes/table-content/table-content.data.ts |   23 +
 .../routes/table-content/table-content.module.less |   33 +
 .../src/routes/table-content/table.api.ts          |   32 +
 .../src/routes/table-content/table.interface.ts    |   36 +
 .../src/routes/table-content/tabs/baseInfo.tsx     |   83 ++
 .../src/routes/table-content/tabs/data-import.tsx  |  249 ++++
 .../src/routes/table-content/tabs/data.pre.tsx     |  106 ++
 .../table-content/tabs/dataImport-menu/index.tsx   |   79 ++
 .../src/routes/table-content/tabs/tabs.api.ts      |   29 +
 .../routes/table-content/tabs/tabs.interface.ts    |   35 +
 .../src/routes/table-content/tabs/tabs.module.less |   74 ++
 .../src/routes/tree/create-menu/create.module.less |   27 +
 .../src/routes/tree/create-menu/databaseModal.tsx  |  107 ++
 .../src/routes/tree/create-menu/index.tsx          |   79 ++
 manager/doris-manager/src/routes/tree/index.tsx    |  143 +++
 manager/doris-manager/src/routes/tree/tree.api.ts  |   47 +
 manager/doris-manager/src/routes/tree/tree.data.ts |   24 +
 .../src/routes/tree/tree.interface.ts              |   45 +
 .../doris-manager/src/routes/tree/tree.module.less |   78 ++
 .../doris-manager/src/routes/tree/tree.service.ts  |   31 +
 .../src/routes/user-setting/index.module.less      |   42 +
 .../src/routes/user-setting/index.tsx              |  224 ++++
 .../src/routes/user-setting/user.api.js            |   33 +
 .../routes/workspace/components/editor/edito.less  |    0
 .../components/editor/editor.interface.less        |    0
 .../routes/workspace/components/editor/editor.tsx  |   24 +
 .../src/routes/workspace/workspace.interface.ts    |   22 +
 .../src/routes/workspace/workspace.tsx             |   35 +
 manager/doris-manager/src/types/global.d.ts        |   21 +
 manager/doris-manager/src/utils/auth.ts            |   29 +
 manager/doris-manager/src/utils/event-emitter.ts   |   60 +
 manager/doris-manager/src/utils/http.ts            |  106 ++
 manager/doris-manager/src/utils/utils.ts           |   69 ++
 manager/doris-manager/theme.js                     |   52 +
 manager/doris-manager/tsconfig.json                |   53 +
 manager/doris-manager/version.json                 |    3 +
 manager/doris-manager/webpack.config.js            |   31 +
 manager/general/pom.xml                            |   33 +
 .../stack/component/ClusterUserComponent.java      |  183 +++
 .../doris/stack/component/IdaasComponent.java      |  160 +++
 .../doris/stack/component/LdapComponent.java       |  269 +++++
 .../doris/stack/component/MailComponent.java       |  460 ++++++++
 .../doris/stack/component/SettingComponent.java    |  273 +++++
 .../stack/component/UserActivityComponent.java     |   69 ++
 .../apache/doris/stack/connector/LdapClient.java   |  163 +++
 .../apache/doris/stack/constant/ConstantDef.java   |  114 ++
 .../doris/stack/constant/EnvironmentDefine.java    |  100 ++
 .../doris/stack/constant/PropertyDefine.java       |   82 ++
 .../doris/stack/controller/BaseController.java     |   48 +
 .../doris/stack/controller/UtilController.java     |   56 +
 .../stack/controller/config/EmailController.java   |   93 ++
 .../stack/controller/config/IdaasController.java   |   70 ++
 .../stack/controller/config/LdapController.java    |   70 ++
 .../stack/controller/config/SettingController.java |  126 +++
 .../controller/user/AuthenticationController.java  |  116 ++
 .../stack/controller/user/UserController.java      |  218 ++++
 .../apache/doris/stack/dao/ActivityRepository.java |   51 +
 .../doris/stack/dao/ClusterInfoRepository.java     |   42 +
 .../doris/stack/dao/CoreSessionRepository.java     |   61 +
 .../apache/doris/stack/dao/CoreUserRepository.java |   53 +
 .../doris/stack/dao/LoginHistoryRepository.java    |   33 +
 .../dao/PermissionsGroupMembershipRepository.java  |   64 ++
 .../stack/dao/PermissionsGroupRoleRepository.java  |   56 +
 .../apache/doris/stack/dao/SettingRepository.java  |   41 +
 .../doris/stack/dao/StudioSettingRepository.java   |   33 +
 .../doris/stack/dao/SuperUserRepository.java       |   46 +
 .../apache/doris/stack/entity/ActivityEntity.java  |  140 +++
 .../doris/stack/entity/ClusterInfoEntity.java      |  138 +++
 .../doris/stack/entity/CoreSessionEntity.java      |   51 +
 .../apache/doris/stack/entity/CoreUserEntity.java  |  211 ++++
 .../doris/stack/entity/LoginHistoryEntity.java     |   71 ++
 .../entity/PermissionsGroupMembershipEntity.java   |   59 +
 .../stack/entity/PermissionsGroupRoleEntity.java   |   67 ++
 .../apache/doris/stack/entity/SettingEntity.java   |   45 +
 .../doris/stack/entity/StudioSettingEntity.java    |   48 +
 .../doris/stack/entity/StudioSettingEntityPk.java  |   34 +
 .../apache/doris/stack/entity/SuperUserEntity.java |   44 +
 .../stack/exception/AuthorizationException.java    |   30 +
 .../doris/stack/exception/BadRequestException.java |   26 +
 .../stack/exception/DorisConnectionException.java  |   27 +
 .../exception/DorisHttpPortErrorException.java     |   34 +
 .../stack/exception/DorisIpErrorException.java     |   34 +
 .../exception/DorisJdbcPortErrorException.java     |   34 +
 .../exception/DorisSpaceDuplicatedException.java   |   27 +
 .../exception/DorisUerOrPassErrorException.java    |   34 +
 .../exception/DorisUserNoPermissionException.java  |   34 +
 .../doris/stack/exception/EmailSendException.java  |   31 +
 .../stack/exception/HdfsUnknownHostException.java  |   27 +
 .../doris/stack/exception/HdfsUrlException.java    |   27 +
 .../stack/exception/IdaasConnectionException.java  |   27 +
 .../stack/exception/IdaasNotExistException.java    |   28 +
 .../doris/stack/exception/InputDataException.java  |   28 +
 .../stack/exception/InputFormatException.java      |   27 +
 .../stack/exception/InvalidDataException.java      |   28 +
 .../stack/exception/LdapConnectionException.java   |   27 +
 .../stack/exception/LdapNotExistException.java     |   28 +
 .../stack/exception/MetaDataSyncException.java     |   26 +
 .../stack/exception/NameDuplicatedException.java   |   28 +
 .../exception/NoAdminPermissionException.java      |   27 +
 .../stack/exception/NoPermissionException.java     |   27 +
 .../stack/exception/PaloRequestException.java      |   26 +
 .../stack/exception/PasswordFormatException.java   |   28 +
 .../stack/exception/RequestFieldNullException.java |   31 +
 .../stack/exception/ResetPasswordException.java    |   29 +
 .../exception/ResetPasswordTokenException.java     |   31 +
 .../doris/stack/exception/SqlSyntaxException.java  |   28 +
 .../doris/stack/exception/StudioInitException.java |   28 +
 .../stack/exception/StudioNotInitException.java    |   28 +
 .../doris/stack/exception/UnknownException.java    |   25 +
 .../stack/exception/UserDisabledException.java     |   27 +
 .../exception/UserEmailDuplicatedException.java    |   27 +
 .../exception/UserFailedLoginTooManyException.java |   27 +
 .../doris/stack/exception/UserLoginException.java  |   27 +
 .../stack/exception/UserLoginTooManyException.java |   27 +
 .../stack/exception/UserNotExistException.java     |   27 +
 .../stack/model/activity/ActivityInfoResp.java     |  177 +++
 .../stack/model/activity/ActivityModelType.java    |   31 +
 .../stack/model/activity/ActivityViewInfoResp.java |   91 ++
 .../doris/stack/model/activity/ModelObject.java    |   50 +
 .../apache/doris/stack/model/activity/Topic.java   |   35 +
 .../doris/stack/model/ldap/LdapConnectionInfo.java |   46 +
 .../doris/stack/model/ldap/LdapUserInfo.java       |   40 +
 .../doris/stack/model/ldap/LdapUserInfoReq.java    |   34 +
 .../doris/stack/model/meta/DataBaseResp.java       |  445 ++++++++
 .../apache/doris/stack/model/meta/TableResp.java   |  402 +++++++
 .../model/request/config/ConfigUpdateReq.java      |   93 ++
 .../stack/model/request/config/EmailInfo.java      |  172 +++
 .../model/request/config/IdaasSettingReq.java      |   53 +
 .../stack/model/request/config/InitStudioReq.java  |   39 +
 .../stack/model/request/config/LdapSettingReq.java |  105 ++
 .../model/request/config/StudioSettingReq.java     |   30 +
 .../stack/model/request/config/TestEmailReq.java   |   25 +
 .../model/request/space/ClusterCreateReq.java      |   53 +
 .../request/space/ClusterInitValidateReq.java      |   40 +
 .../stack/model/request/space/ClusterType.java     |   27 +
 .../model/request/space/UserSpaceCreateReq.java    |   72 ++
 .../model/request/space/UserSpaceUpdateReq.java    |   38 +
 .../stack/model/request/user/PasswordResetReq.java |   43 +
 .../model/request/user/PasswordUpdateReq.java      |   61 +
 .../doris/stack/model/request/user/UserAddReq.java |   54 +
 .../stack/model/request/user/UserGroupRole.java    |   27 +
 .../stack/model/request/user/UserLoginReq.java     |   42 +
 .../stack/model/request/user/UserSpaceReq.java     |   40 +
 .../stack/model/request/user/UserUpdateReq.java    |   43 +
 .../doris/stack/model/response/config/GeoInfo.java |   61 +
 .../stack/model/response/config/IdaasResult.java   |   48 +
 .../model/response/config/IdaasSettingResp.java    |   40 +
 .../model/response/config/LdapSettingResp.java     |   57 +
 .../model/response/config/PasswordComplexity.java  |   31 +
 .../model/response/config/PremiumFeatures.java     |   37 +
 .../model/response/config/SessionSettingResp.java  | 1192 +++++++++++++++++++
 .../stack/model/response/config/SettingItem.java   |   92 ++
 .../doris/stack/model/response/config/Version.java |   38 +
 .../stack/model/response/config/VersionInfo.java   |   33 +
 .../stack/model/response/space/UserSpaceInfo.java  |   63 ++
 .../stack/model/response/user/GroupMember.java     |   69 ++
 .../model/response/user/PasswordResetResp.java     |   45 +
 .../model/response/user/UserGroupMembership.java   |   69 ++
 .../doris/stack/model/response/user/UserInfo.java  |  292 +++++
 .../org/apache/doris/stack/rest/ResponseBody.java  |   93 ++
 .../doris/stack/rest/ResponseEntityBuilder.java    |   70 ++
 .../doris/stack/rest/RestApiExceptionHandler.java  |   94 ++
 .../apache/doris/stack/rest/RestApiStatusCode.java |   36 +
 .../apache/doris/stack/service/BaseService.java    |   38 +
 .../apache/doris/stack/service/UtilService.java    |  226 ++++
 .../doris/stack/service/config/ConfigCache.java    |  143 +++
 .../doris/stack/service/config/ConfigConstant.java |  379 +++++++
 .../doris/stack/service/config/ConfigItem.java     |  166 +++
 .../doris/stack/service/config/ConfigValueDef.java |   97 ++
 .../doris/stack/service/config/EmailService.java   |  177 +++
 .../doris/stack/service/config/IdaasService.java   |   87 ++
 .../doris/stack/service/config/LdapService.java    |   87 ++
 .../doris/stack/service/config/SettingService.java |  346 ++++++
 .../stack/service/user/AuthenticationService.java  | 1193 ++++++++++++++++++++
 .../doris/stack/service/user/UserService.java      |  676 +++++++++++
 .../org/apache/doris/stack/util/CredsUtil.java     |  104 ++
 .../java/org/apache/doris/stack/util/ListUtil.java |  119 ++
 .../org/apache/doris/stack/util/LogBuilder.java    |  113 ++
 .../org/apache/doris/stack/util/PropertyUtil.java  |  250 ++++
 .../java/org/apache/doris/stack/util/UuidUtil.java |   38 +
 .../doris/stack/component/LdapComponentTest.java   |  220 ++++
 .../doris/stack/component/MailComponentTest.java   |  248 ++++
 .../stack/component/SettingComponentTest.java      |  359 ++++++
 .../stack/service/config/EmailServiceTest.java     |  208 ++++
 .../stack/service/config/LdapServiceTest.java      |  115 ++
 .../stack/service/config/SettingServiceTest.java   |  376 ++++++
 .../service/user/AuthenticationServiceTest.java    |  794 +++++++++++++
 .../doris/stack/service/user/UserServiceTest.java  |  762 +++++++++++++
 manager/manager-bin/agent/bin/agent_start.sh       |   91 ++
 manager/manager-bin/agent/bin/agent_stop.sh        |   43 +
 manager/manager-bin/agent/bin/install_be.sh        |   76 ++
 manager/manager-bin/agent/bin/install_broker.sh    |   76 ++
 manager/manager-bin/agent/bin/install_fe.sh        |   76 ++
 manager/manager-bin/agent/bin/process_exist.sh     |   28 +
 manager/manager-bin/start_manager.sh               |  100 ++
 manager/manager-bin/stop_manager.sh                |   20 +
 manager/manager-server/pom.xml                     |   75 ++
 .../java/org/apache/doris/stack/DorisManager.java  |   65 ++
 .../apache/doris/stack/ManagerSwaggerConfig.java   |   55 +
 .../org/apache/doris/stack/StartManagerRunner.java |   56 +
 .../doris/stack/controller/IndexController.java    |   36 +
 .../stack/controller/PaloUserSpaceController.java  |  139 +++
 .../doris/stack/service/PaloUserSpaceService.java  |  511 +++++++++
 .../src/main/resources/logback-spring.xml          |  170 +++
 .../src/main/resources/mail/_footer.mustache       |    9 +
 .../src/main/resources/mail/_footer_pulse.mustache |   11 +
 .../src/main/resources/mail/_header.mustache       |   15 +
 .../src/main/resources/mail/_logo.mustache         |    3 +
 .../resources/mail/alert_new_confirmation.mustache |    4 +
 .../resources/mail/alert_unsubscribed.mustache     |    3 +
 .../main/resources/mail/alert_was_deleted.mustache |    4 +
 .../resources/mail/alert_you_were_added.mustache   |    5 +
 .../main/resources/mail/new_user_invite.mustache   |   25 +
 .../main/resources/mail/password_reset.mustache    |   15 +
 .../mail/user_joined_notification.mustache         |   26 +
 .../stack/service/PaloUserSpaceServiceTest.java    |  592 ++++++++++
 manager/manager/pom.xml                            |   49 +
 .../doris/stack/component/DatabuildComponent.java  |   50 +
 .../stack/component/ManagerMetaSyncComponent.java  |  351 ++++++
 .../stack/component/ManagerMetaSynchronizer.java   |   60 +
 .../stack/connector/HttpClientPoolManager.java     |  335 ++++++
 .../apache/doris/stack/connector/PaloClient.java   |   77 ++
 .../stack/connector/PaloFileUploadClient.java      |  186 +++
 .../stack/connector/PaloForwardManagerClient.java  |   80 ++
 .../doris/stack/connector/PaloLoginClient.java     |   56 +
 .../doris/stack/connector/PaloMetaInfoClient.java  |  143 +++
 .../doris/stack/connector/PaloMonitorClient.java   |  441 ++++++++
 .../doris/stack/connector/PaloQueryClient.java     |  143 +++
 .../doris/stack/connector/PaloStatisticClient.java |   60 +
 .../controller/construct/ClusterController.java    |   59 +
 .../controller/construct/DataImportController.java |  155 +++
 .../controller/construct/DataManageController.java |  122 ++
 .../controller/construct/MetadataController.java   |  128 +++
 .../construct/NativeQueryController.java           |   61 +
 .../controller/manager/PaloManagerController.java  |  230 ++++
 .../controller/monitor/PaloMonitorController.java  |  127 +++
 .../doris/stack/dao/DataImportTaskRepository.java  |   47 +
 .../doris/stack/dao/ManagerDatabaseRepository.java |   38 +
 .../doris/stack/dao/ManagerFieldRepository.java    |   38 +
 .../doris/stack/dao/ManagerTableRepository.java    |   35 +
 .../doris/stack/driver/DorisDataBuildDriver.java   |  310 +++++
 .../doris/stack/driver/JdbcSampleClient.java       |   55 +
 .../doris/stack/entity/DataImportTaskEntity.java   |  166 +++
 .../doris/stack/entity/ManagerDatabaseEntity.java  |   69 ++
 .../doris/stack/entity/ManagerFieldEntity.java     |  102 ++
 .../doris/stack/entity/ManagerTableEntity.java     |   75 ++
 .../doris/stack/model/palo/ClusterMonitorInfo.java |   44 +
 .../stack/model/palo/ClusterOverviewInfo.java      |   42 +
 .../doris/stack/model/palo/HdfsFileInfo.java       |   36 +
 .../doris/stack/model/palo/HdfsFilePreview.java    |   56 +
 .../doris/stack/model/palo/HdfsFilePreviewReq.java |   77 ++
 .../doris/stack/model/palo/HdfsImportTaskInfo.java |  141 +++
 .../doris/stack/model/palo/LocalFileInfo.java      |   42 +
 .../stack/model/palo/LocalFileSubmitResult.java    |   58 +
 .../doris/stack/model/palo/PaloResponseEntity.java |   45 +
 .../doris/stack/model/palo/TableSchemaInfo.java    |   87 ++
 .../stack/model/request/construct/DbCreateReq.java |   33 +
 .../stack/model/request/construct/FieldInfo.java   |   84 ++
 .../model/request/construct/FileImportReq.java     |   36 +
 .../model/request/construct/HdfsConnectReq.java    |   44 +
 .../model/request/construct/HdfsImportReq.java     |   44 +
 .../model/request/construct/TableCreateReq.java    |  147 +++
 .../model/request/monitor/ClusterMonitorReq.java   |   36 +
 .../response/construct/ClusterOverviewResp.java    |   52 +
 .../response/construct/DataImportTaskPageResp.java |   89 ++
 .../model/response/construct/DatabaseResp.java     |   38 +
 .../model/response/construct/HdfsPreviewResp.java  |   34 +
 .../model/response/construct/NativeQueryResp.java  |   57 +
 .../stack/model/response/construct/TableResp.java  |   44 +
 .../stack/service/construct/ClusterService.java    |   58 +
 .../stack/service/construct/DataDescription.java   |   32 +
 .../stack/service/construct/DataImportService.java |  435 +++++++
 .../stack/service/construct/DataManageService.java |  216 ++++
 .../stack/service/construct/MetadataService.java   |  318 ++++++
 .../service/construct/NativeQueryService.java      |   85 ++
 .../stack/service/manager/PaloManagerService.java  |   69 ++
 .../stack/service/monitor/PaloMonitorService.java  |  160 +++
 .../stack/component/DatabuildComponentTest.java    |   84 ++
 .../component/ManagerMetaSyncComponentTest.java    |  416 +++++++
 .../stack/driver/DorisDataBuildDriverTest.java     |  367 ++++++
 .../service/construct/DataImportServiceTest.java   |  498 ++++++++
 .../service/construct/DataManageServiceTest.java   |  285 +++++
 .../service/construct/MetadataServiceTest.java     |  357 ++++++
 .../service/construct/NativeQueryServiceTest.java  |  131 +++
 .../service/monitor/PaloMonitorServiceTest.java    |  121 ++
 manager/pom.xml                                    |  270 +++++
 567 files changed, 51033 insertions(+)

diff --git a/.asf.yaml b/.asf.yaml
new file mode 100644
index 0000000..46f0303
--- /dev/null
+++ b/.asf.yaml
@@ -0,0 +1,40 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+github:
+  description: Flink/Spark Connectors for Apache Doris(Incubating)
+  homepage: https://doris.apache.org/
+  labels:
+    - data-warehousing
+    - mpp
+    - olap
+    - dbms
+    - apache
+    - doris
+    - manager
+    - ui
+  enabled_merge_buttons:
+    squash:  true
+    merge:   false
+    rebase:  false
+  protected_branches:
+    master:
+      required_pull_request_reviews:
+        dismiss_stale_reviews: true
+        required_approving_review_count: 1
+  notifications:
+    pullrequests_status:  dev@doris.apache.org
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..acabcb1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,109 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Doris Bug report
+title: "[Bug] "
+description: Problems and issues with code of Apache Doris
+labels: [ "kind/bug" ]
+body:
+  - type: markdown
+    attributes:
+      value: |
+        Thank you very much for submitting feedback to Doris to help Doris develop better.
+
+        If it is an idea or help wanted, please go to:
+
+        1. [Dev Mail List](mailto:dev@doris.apache.org): This will be your FASTEST way to get help![How to subscribe](mailto:dev-subscribe@doris.apache.org)
+        2. [Github Discussion](https://github.com/apache/incubator-doris/discussions)
+
+  - type: checkboxes
+    attributes:
+      label: Search before asking
+      description: >
+        Please make sure to search in the [issues](https://github.com/apache/incubator-doris/issues?q=is%3Aissue) first to see
+        whether the same issue was reported already.
+      options:
+        - label: >
+            I had searched in the [issues](https://github.com/apache/incubator-doris/issues?q=is%3Aissue) and found no similar
+            issues.
+          required: true
+
+  - type: textarea
+    attributes:
+      label: Version
+      description: What is the current version 
+      placeholder: >
+        Please provide the version you are using.
+        If it is the trunk version, please input commit id.
+    validations:
+      required: true
+
+  - type: textarea
+    attributes:
+      label: What's Wrong?
+      description: Describe the bug.
+      placeholder: >
+        Describe the specific problem, the more detailed the better.
+    validations:
+      required: true
+
+  - type: textarea
+    attributes:
+      label: What You Expected?
+    validations:
+      required: true
+
+  - type: textarea
+    attributes:
+      label: How to Reproduce?
+      placeholder: >
+        Please try to give reproducing steps to facilitate quick location of the problem.
+
+        - What actions were performed
+        - Table building statement
+        - Import statement
+        - Cluster information: number of nodes, configuration, etc.
+
+        If it is hard to reproduce, please also explain the general scene.
+
+  - type: textarea
+    attributes:
+      label: Anything Else?
+
+  - type: checkboxes
+    attributes:
+      label: Are you willing to submit PR?
+      description: >
+        We very much look forward to developers or users to help solve the Doris problem together.
+        If you are willing to submit a PR to fix this problem, please tick it.
+      options:
+        - label: Yes I am willing to submit a PR!
+
+  - type: checkboxes
+    attributes:
+      label: Code of Conduct
+      description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
+      options:
+        - label: >
+            I agree to follow this project's
+            [Code of Conduct](https://www.apache.org/foundation/policies/conduct)
+          required: true
+
+  - type: markdown
+    attributes:
+      value: "Thanks for completing our form!"
+
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..8e0108e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+blank_issues_enabled: true
+contact_links:
+  - name: Ask a question or get support
+    url: https://github.com/apache/incubator-doris/discussions
+    about: Ask a question or request support for using Apache Doris
+
diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml
new file mode 100644
index 0000000..df617e8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enhancement.yml
@@ -0,0 +1,76 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Doris enhancement
+description: Add an enhanment for Apache Doris
+title: "[Enhancement] "
+labels: [ "kind/enhancement" ]
+body:
+  - type: markdown
+    attributes:
+      value: |
+        Thank you very much for your good enhancement for Doris.
+
+        Please help sync to the [Dev Mail List](mailto:dev@doris.apache.org). You will get FASTER help![How to subscribe](mailto:dev-subscribe@doris.apache.org)
+
+  - type: checkboxes
+    attributes:
+      label: Search before asking
+      description: >
+        Please make sure to search in the [issues](https://github.com/apache/incubator-doris/issues?q=is%3Aissue) first to see
+        whether the same issue was reported already.
+      options:
+        - label: >
+            I had searched in the [issues](https://github.com/apache/incubator-doris/issues?q=is%3Aissue) and found no similar
+            issues.
+          required: true
+
+  - type: textarea
+    attributes:
+      label: Description
+      description: Describe the enhancement what you want, including motivation if it exists.
+
+  - type: textarea
+    attributes:
+      label: Solution
+      placeholder: >
+        Add overview of proposed solution. 
+        
+        Add related materials like links if they exist.
+
+  - type: checkboxes
+    attributes:
+      label: Are you willing to submit PR?
+      description: >
+        We very much look forward to developers or users to help develop the Doris together.
+        If you are willing to submit a PR to implement this feature, please tick it.
+      options:
+        - label: Yes I am willing to submit a PR!
+
+  - type: checkboxes
+    attributes:
+      label: Code of Conduct
+      description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
+      options:
+        - label: >
+            I agree to follow this project's
+            [Code of Conduct](https://www.apache.org/foundation/policies/conduct)
+          required: true
+
+  - type: markdown
+    attributes:
+      value: "Thanks for completing our form!"
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
new file mode 100644
index 0000000..0a7d82e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.yml
@@ -0,0 +1,78 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+name: Doris feature request
+description: Suggest an idea for Apache Doris
+title: "[Feature] "
+labels: [ "kind/feature" ]
+body:
+  - type: markdown
+    attributes:
+      value: |
+        Thank you very much for your good ideas and suggestions for Doris
+
+        Please help sync to the [Dev Mail List](mailto:dev@doris.apache.org). You will get FASTER help![How to subscribe](mailto:dev-subscribe@doris.apache.org)
+
+  - type: checkboxes
+    attributes:
+      label: Search before asking
+      description: >
+        Please make sure to search in the [issues](https://github.com/apache/incubator-doris/issues?q=is%3Aissue) first to see
+        whether the same issue was reported already.
+      options:
+        - label: >
+            I had searched in the [issues](https://github.com/apache/incubator-doris/issues?q=is%3Aissue) and found no similar
+            issues.
+          required: true
+
+  - type: textarea
+    attributes:
+      label: Description
+      description: Describe your ideas and needs.
+
+  - type: textarea
+    attributes:
+      label: Use case
+      placeholder: >
+        What problem does this feature mainly solve, or what scenarios it is suitable for.
+
+  - type: textarea
+    attributes:
+      label: Related issues
+      description: Is there currently another issue associated with this?
+
+  - type: checkboxes
+    attributes:
+      label: Are you willing to submit PR?
+      description: >
+        We very much look forward to developers or users to help develop the Doris together.
+        If you are willing to submit a PR to implement this feature, please tick it.
+      options:
+        - label: Yes I am willing to submit a PR!
+
+  - type: checkboxes
+    attributes:
+      label: Code of Conduct
+      description: The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.
+      options:
+        - label: >
+            I agree to follow this project's
+            [Code of Conduct](https://www.apache.org/foundation/policies/conduct)
+          required: true
+
+  - type: markdown
+    attributes:
+      value: "Thanks for completing our form!"
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..6f56b55
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,19 @@
+# Proposed changes
+
+Issue Number: close #xxx
+
+## Problem Summary:
+
+Describe the overview of changes.
+
+## Checklist(Required)
+
+1. Does it affect the original behavior: (Yes/No/I Don't know)
+2. Has unit tests been added: (Yes/No/No Need)
+3. Has document been added or modified: (Yes/No/No Need)
+4. Does it need to update dependencies: (Yes/No)
+5. Are there any changes that cannot be rolled back: (Yes/No)
+
+## Further comments
+
+If this is a relatively large or complex change, kick off the discussion at [dev@doris.apache.org](mailto:dev@doris.apache.org) by explaining why you chose the solution you did and what alternatives you considered, etc...
diff --git a/.github/workflows/approve-label-trigger.yml b/.github/workflows/approve-label-trigger.yml
new file mode 100644
index 0000000..1a9cb84
--- /dev/null
+++ b/.github/workflows/approve-label-trigger.yml
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+---
+name: Label when reviewed
+on: pull_request_review
+jobs:
+
+  label-when-reviewed:
+    name: "Label PRs when reviewed"
+    runs-on: ubuntu-latest
+    steps:
+      - name: "Do nothing. Only trigger corresponding workflow_run event"
+        run: echo
diff --git a/.github/workflows/approve-label.yml b/.github/workflows/approve-label.yml
new file mode 100644
index 0000000..f022578
--- /dev/null
+++ b/.github/workflows/approve-label.yml
@@ -0,0 +1,67 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+---
+name: Label when approved workflow run
+on:
+  workflow_run:
+    workflows: ["Label when reviewed"]
+    types: ['requested']
+permissions:
+  # All other permissions are set to none
+  checks: write
+  contents: read
+  pull-requests: write
+
+jobs:
+
+  label-when-approved:
+    name: "Label when approved"
+    runs-on: ubuntu-latest
+    outputs:
+      isApprovedByCommiters: ${{ steps.label-when-approved-by-commiters.outputs.isApproved }}
+      isApprovedByAnyone: ${{ steps.label-when-approved-by-anyone.outputs.isApproved }}
+    steps:
+      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+        uses: actions/checkout@v2
+        with:
+          persist-credentials: false
+          submodules: recursive
+      - name: "Get information about the original trigger of the run"
+        uses: ./.github/actions/get-workflow-origin
+        id: source-run-info
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          sourceRunId: ${{ github.event.workflow_run.id }}
+      - name: Label when approved by commiters
+        uses: ./.github/actions/label-when-approved-action
+        id: label-when-approved-by-commiters
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          label: 'approved'
+          require_committers_approval: 'true'
+          remove_label_when_approval_missing: 'true'
+          pullRequestNumber: ${{ steps.source-run-info.outputs.pullRequestNumber }}
+          comment: 'PR approved by at least one committer and no changes requested.'
+      - name: Label when approved by anyone
+        uses: ./.github/actions/label-when-approved-action
+        id: label-when-approved-by-anyone
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          label: 'reviewed'
+          pullRequestNumber: ${{ steps.source-run-info.outputs.pullRequestNumber }}
+          comment: 'PR approved by anyone and no changes requested.'
diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml
new file mode 100644
index 0000000..06616ab
--- /dev/null
+++ b/.github/workflows/build-extension.yml
@@ -0,0 +1,49 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+---
+name: Build Manager
+on:
+  pull_request:
+  push:
+
+jobs:
+  build-manager:
+    name: "Build Manager"
+    runs-on: ubuntu-latest
+    defaults:
+      run:
+        shell: bash
+    steps:
+    - name: Checkout
+      uses: actions/checkout@master
+
+    - name: Setup java
+      uses: actions/setup-java@v2
+      with:
+        distribution: adopt
+        java-version: '8'
+
+    - name: Setup thrift
+      run: |
+        sudo apt-get update
+        sudo DEBIAN_FRONTEND=noninteractive apt-get install -y thrift-compiler=0.13.0-2build2
+        thrift --version
+        touch custom_env.sh
+        echo 'export THRIFT_BIN=/usr/bin/thrift' >> custom_env.sh
+
+
diff --git a/.github/workflows/license-eyes.yml b/.github/workflows/license-eyes.yml
new file mode 100644
index 0000000..c9b4cd2
--- /dev/null
+++ b/.github/workflows/license-eyes.yml
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+---
+name: License Check
+on:
+  pull_request:
+  push:
+    branches:
+      - master
+jobs:
+  license-check:
+    name: "License Check"
+    runs-on: ubuntu-latest
+    steps:
+      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+        uses: actions/checkout@v2
+      - name: Check License
+        uses: apache/skywalking-eyes@v0.2.0
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..876b818
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+custom_env.sh
+flink-doris-connector/dependency-reduced-pom.xml
+flink-doris-connector/output/
+flink-doris-connector/target/
+spark-doris-connector/dependency-reduced-pom.xml
+spark-doris-connector/output/
+spark-doris-connector/target/
diff --git a/.licenserc.yaml b/.licenserc.yaml
new file mode 100644
index 0000000..c1f8109
--- /dev/null
+++ b/.licenserc.yaml
@@ -0,0 +1,36 @@
+header:
+  license:
+    spdx-id: Apache-2.0
+    copyright-owner: Apache Software Foundation
+
+  paths-ignore:
+    - 'dist'
+    - 'licenses'
+    - '**/*.md'
+    - 'LICENSE'
+    - 'NOTICE'
+    - 'DISCLAIMER'
+    - '.clang-format'
+    - '.clang-format-ignore'
+    - '.gitattributes'
+    - '.gitignore'
+    - '.gitmodules'
+    - '.licenserc.yaml'
+    - '.rat-excludes'
+    - 'be/src/common/status.cpp'
+    - 'be/src/common/status.h'
+    - 'be/src/env/env.h'
+    - 'be/src/env/env_posix.cpp'
+    - '**/glibc-compatibility/**'
+    - '**/gutil/**'
+    - '**/test_data/**'
+    - '**/jmockit/**'
+    - '**/*.json'
+    - '**/*.dat'
+    - '**/*.svg'
+    - '**/*.md5'
+    - '**/*.patch'
+    - '**/*.log'
+    - 'custom_env.sh.tpl'
+
+  comment: on-failure
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..c9b8f87
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,95 @@
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at dev@doris.apache.org. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..3c353cb
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,24 @@
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Contribute to Doris
+
+Thank you very much for your interest in the Doris project. We welcome your suggestions, comments (including criticisms), comments and contributions to the Doris project.
+
+For more information on how to contribute to Doris, please go to the Doris main repository [CONTRIBUTING](https://github.com/apache/incubator-doris/blob/master/CONTRIBUTING.md)
diff --git a/CONTRIBUTING_CN.md b/CONTRIBUTING_CN.md
new file mode 100644
index 0000000..5dc5fbe
--- /dev/null
+++ b/CONTRIBUTING_CN.md
@@ -0,0 +1,24 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# 为 Doris 做贡献
+
+非常感谢您对 Doris 项目感兴趣,我们非常欢迎您对 Doris 项目的各种建议、意见(包括批评)、评论和贡献。
+
+关于如何为 Doris 做贡献,请前往 Doris 主库查阅 [CONTRIBUTING_CN](https://github.com/apache/incubator-doris/blob/master/CONTRIBUTING_CN.md)
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..57bc88a
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..f8c43b1
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Doris (incubating)
+Copyright 2018-2022 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..edf5ab8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,47 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Apache Doris (incubating) Manager
+
+[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
+[![Join the Doris Community at Slack](https://img.shields.io/badge/chat-slack-brightgreen)](https://join.slack.com/t/apachedoriscommunity/shared_invite/zt-11jb8gesh-7IukzSrdea6mqoG0HB4gZg)
+
+The repository contains Manager for Apache Doris (incubating)
+
+## License
+
+[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+## Report issues or submit pull request
+
+If you find any bugs, feel free to file a [GitHub issue](https://github.com/apache/incubator-doris/issues) or fix it by submitting a [pull request](https://github.com/apache/incubator-doris/pulls).
+
+## Contact Us
+
+Contact us through the following mailing list.
+
+| Name                                                                          | Scope                           |                                                                 |                                                                     |                                                                              |
+|:------------------------------------------------------------------------------|:--------------------------------|:----------------------------------------------------------------|:--------------------------------------------------------------------|:-----------------------------------------------------------------------------|
+| [dev@doris.apache.org](mailto:dev@doris.apache.org)     | Development-related discussions | [Subscribe](mailto:dev-subscribe@doris.apache.org)   | [Unsubscribe](mailto:dev-unsubscribe@doris.apache.org)   | [Archives](http://mail-archives.apache.org/mod_mbox/doris-dev/)   |
+
+## Links
+
+* Doris official site - <http://doris.incubator.apache.org>
+* Developer Mailing list - <de...@doris.apache.org>. Mail to <de...@doris.apache.org>, follow the reply to subscribe the mail list.
+* Slack channel - [Join the Slack](https://join.slack.com/t/apachedoriscommunity/shared_invite/zt-11jb8gesh-7IukzSrdea6mqoG0HB4gZg)
diff --git a/manager/README.md b/manager/README.md
new file mode 100644
index 0000000..713fee6
--- /dev/null
+++ b/manager/README.md
@@ -0,0 +1,103 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Apache Doris Manager (incubating)
+[![Join the chat at https://gitter.im/apache-doris/Lobby](https://badges.gitter.im/apache-doris/Lobby.svg)](https://gitter.im/apache-doris/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+Apache Doris Manager is used to manage the doris cluster, such as monitoring cluster, installing the cluster, upgrading the cluster, starting and stopping services, etc.
+
+## 1. Compile and install
+
+### Step1: build
+```
+$ sh build.sh
+```
+Compiles the front and back ends of the project. After compilation, a tar package will be generated in the output/ directory and doris-manager-1.0.0.tar.gz package.The content of the compiled output is:
+```
+agent/, doris manger agent
+    bin/
+        agent_start.sh, doris manger agent startup script
+        agent_stop.sh, doris manger agent stop script
+        install_be.sh, doris be install script
+        install_fe.sh, doris fe install script
+        install_broker.sh, doris broker install script
+        process_exist.sh, doris process detection script
+    lib/
+        dm-agent.jar, executable package of doris manger agent
+server/, doris manger server
+    conf/
+        manager.conf, doris manger server configuration file
+    web-resource/, doris manger server front static resources
+    lib/
+        doris-manager.jar, executable package of doris manger server
+    bin/
+        start_manager.sh, doris manger server startup script
+        stop_manager.sh, doris manger server stop script
+```
+
+### Step2: install manager server
+#### 1) Unzip the installation package
+Copy doris-manager-1.0.0.tar.gz tar package to the the machine where the manager server needs to be installed.
+```
+$ tar -zxvf doris-manager-1.0.0.tar.gz
+$ cd server
+```
+#### 2) Modify profile
+Edit conf/manager.conf
+```$xslt
+Start HTTP port of the service
+STUDIO_PORT=8080
+
+The type of database where back-end data is stored, including MySQL / H2 / PostgreSQL. MySQL is supported by default
+MB_DB_TYPE=mysql
+
+Database connection information
+
+If you are configuring a H2 type database, you do not need to configure this information, and the data will be stored locally as a local file
+
+For MySQL / PostgreSQL, you need to configure the following connection information
+
+Database address
+MB_DB_HOST=
+
+Database port
+MB_DB_PORT=3306
+
+Database access port
+MB_DB_USER=
+
+Database access password
+MB_DB_PASS=123456
+
+Database name of the database
+MB_DB_DBNAME
+```
+
+#### 3) Start manager server
+Start the manager service after decompression and configuration.
+```
+$ sh bin/start_manager.sh
+```
+#### 4) User manager server
+Browser access ${serverIp}:8080, Manger server has a preset super administrator user. The information is as follows:
+```
+user name: Admin
+password: Admin@123
+(Case sensitive)
+```
\ No newline at end of file
diff --git a/manager/build.sh b/manager/build.sh
new file mode 100644
index 0000000..36b562e
--- /dev/null
+++ b/manager/build.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+echo "build doris manager home path"
+
+echo "build doris manager web start"
+cd doris-manager
+npm install
+npm run build
+echo "build doris manager web end"
+
+cd ../
+echo "copy doris manager web resources to server"
+rm -rf manager-server/src/main/resources/web-resource
+mv doris-manager/dist manager-server/src/main/resources/web-resource
+echo "copy doris manager web resources to server end"
+
+echo "build doris manager server start"
+set -e
+mvn clean install
+echo "build doris manager server end"
+
+echo "copy to output package start"
+rm -rf output
+rm -rf doris-manager-1.0.0.tar.gz
+mkdir -p output
+mkdir -p output/server/lib
+mv manager-server/target/manager-server-1.0.0.jar output/server/lib/doris-manager.jar
+cp -r conf output/server/
+cp -r manager-bin output/
+mv output/manager-bin/agent output/
+mv output/manager-bin output/server/bin
+mkdir -p output/agent/lib
+mv dm-agent/target/dm-agent-1.0.0.jar output/agent/lib/dm-agent.jar
+cp -r manager-server/src/main/resources/web-resource output/server/
+tar -zcvf doris-manager-1.0.0.tar.gz output/
+echo "copy to output package end"
\ No newline at end of file
diff --git a/manager/checkstyle/studio_checks.xml b/manager/checkstyle/studio_checks.xml
new file mode 100644
index 0000000..22fa113
--- /dev/null
+++ b/manager/checkstyle/studio_checks.xml
@@ -0,0 +1,299 @@
+<?xml version="1.0"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<!DOCTYPE module PUBLIC
+        "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+        "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+    Checkstyle configuration that checks the Google coding conventions from:
+    -  Google Java Style
+       https://google-styleguide.googlecode.com/svn-history/r130/trunk/javaguide.html
+    Checkstyle is very configurable. Be sure to read the documentation at
+    http://checkstyle.sf.net (or in your downloaded distribution).
+    Most Checks are configurable, be sure to consult the documentation.
+    To completely disable a check, just comment it out or delete it from the file.
+    Copied from https://github.com/checkstyle/checkstyle/blob/master/google_checks.xml
+ -->
+
+<module name = "Checker">
+    <property name="charset" value="UTF-8"/>
+
+    <property name="severity" value="error"/>
+
+    <!-- Checks for whitespace                               -->
+    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+    <module name="FileTabCharacter">
+        <property name="eachLine" value="true"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="@throw.*\.$"/>
+        <property name="message" value="Period is not needed at the end of the @throw tag."/>
+        <property name="fileExtensions" value=".java"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="@return.*\.$"/>
+        <property name="message" value="Period is not needed at the end of the @return tag."/>
+        <property name="fileExtensions" value=".java"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="@param.*\.$"/>
+        <property name="message" value="Period is not needed at the end of the @param tag."/>
+        <property name="fileExtensions" value=".java"/>
+    </module>
+    <module name="RegexpSingleline">
+<!--        <property name="format" value="TODO[^\(]"/>-->
+<!--        <property name="message" value="TODO must be annotated with the author in the format TODO(author)"/>-->
+        <property name="fileExtensions" value=".java"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="&gt;&gt;&gt;&gt;&gt;&gt;&gt;"/>
+        <property name="message" value="Merge conflicts unresolved."/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="&lt;&lt;&lt;&lt;&lt;&lt;&lt;"/>
+        <property name="message" value="Merge conflicts unresolved."/>
+    </module>
+    <module name="RegexpMultiline">
+<!--        <property name="format" value="\{\n\s*\n"/>-->
+        <property name="format" value="\n{3}"/>
+        <property name="fileExtensions" value=".java"/>
+        <property name="message" value="Extra newline"/>
+    </module>
+<!--    <module name="RegexpMultiline">-->
+<!--        <property name="format" value="\n\s*\n\s*}"/>-->
+<!--        <property name="fileExtensions" value=".java"/>-->
+<!--        <property name="message" value="Extra newline at end of block"/>-->
+<!--    </module>-->
+
+    <!-- All Java AST specific tests live under TreeWalker module. -->
+    <module name="TreeWalker">
+        <module name="OuterTypeFilename"/>
+        <module name="IllegalTokenText">
+            <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
+            <property name="format"
+                      value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
+            <property name="message" value="Avoid using corresponding octal or Unicode escape."/>
+        </module>
+        <module name="AvoidEscapedUnicodeCharacters">
+            <property name="allowEscapesForControlCharacters" value="true"/>
+            <property name="allowByTailComment" value="true"/>
+            <property name="allowNonPrintableEscapes" value="true"/>
+        </module>
+        <module name="LineLength">
+            <property name="max" value="120"/>
+            <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://|^ ([\s\S]*)"/>
+        </module>
+        <module name="AvoidStarImport"/>
+        <module name="UnusedImports">
+            <property name="processJavadoc" value="true"/>
+        </module>
+        <module name="OneTopLevelClass"/>
+        <module name="NoLineWrap"/>
+        <module name="EmptyBlock">
+            <property name="option" value="TEXT"/>
+            <property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF,
+        LITERAL_ELSE, LITERAL_SWITCH"/>
+        </module>
+        <module name="NeedBraces"/>
+        <module name="LeftCurly">
+<!--            <property name="maxLineLength" value="100"/>-->
+        </module>
+        <module name="RightCurly"/>
+        <module name="RightCurly">
+            <property name="option" value="alone"/>
+            <property name="tokens" value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE,
+        LITERAL_DO, STATIC_INIT, INSTANCE_INIT"/>
+        </module>
+        <module name="WhitespaceAround">
+            <property name="allowEmptyConstructors" value="true"/>
+            <property name="allowEmptyMethods" value="true"/>
+            <property name="allowEmptyTypes" value="true"/>
+            <property name="allowEmptyLoops" value="true"/>
+            <message key="ws.notFollowed"
+                     value="WhitespaceAround: ''{0}'' is not followed by whitespace."/>
+            <message key="ws.notPreceded"
+                     value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
+        </module>
+        <module name="OneStatementPerLine"/>
+        <module name="EmptyStatement"/>
+        <module name="MultipleVariableDeclarations"/>
+        <module name="ArrayTypeStyle"/>
+        <module name="MissingSwitchDefault"/>
+        <module name="FallThrough"/>
+        <module name="UpperEll"/>
+        <module name="ModifierOrder"/>
+        <module name="EmptyLineSeparator">
+<!--            <property name="allowNoEmptyLineBetweenFields" value="true"/>-->
+            <property name="tokens" value="PACKAGE_DEF , IMPORT , STATIC_IMPORT , CLASS_DEF , INTERFACE_DEF , ENUM_DEF , STATIC_INIT , INSTANCE_INIT , METHOD_DEF , CTOR_DEF"/>
+        </module>
+        <module name="SeparatorWrap">
+            <property name="tokens" value="DOT"/>
+            <property name="option" value="nl"/>
+        </module>
+        <module name="SeparatorWrap">
+            <property name="tokens" value="COMMA"/>
+            <property name="option" value="EOL"/>
+        </module>
+        <module name="PackageName">
+            <!-- https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html -->
+            <property name="format" value="^[a-z]+(\.[a-z_][a-z0-9_]*)*$"/>
+            <message key="name.invalidPattern"
+                     value="Package name ''{0}'' must match pattern ''{1}''."/>
+        </module>
+        <module name="TypeName">
+            <message key="name.invalidPattern"
+                     value="Type name ''{0}'' must match pattern ''{1}''."/>
+        </module>
+<!--        <module name="MemberName">-->
+<!--            <property name="format" value="^m[A-Z][a-zA-Z0-9]*$"/>-->
+<!--            <message key="name.invalidPattern"-->
+<!--                     value="Member name ''{0}'' must match pattern ''{1}''."/>-->
+<!--        </module>-->
+        <module name="ConstantName"/>
+        <module name="ParameterName">
+            <property name="format" value="[a-zA-Z0-9]*$"/>
+            <message key="name.invalidPattern"
+                     value="Parameter name ''{0}'' must match pattern ''{1}''."/>
+        </module>
+        <module name="LocalVariableName">
+            <property name="tokens" value="VARIABLE_DEF"/>
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+            <property name="allowOneCharVarInForLoop" value="true"/>
+            <message key="name.invalidPattern"
+                     value="Local variable name ''{0}'' must match pattern ''{1}''."/>
+        </module>
+        <module name="ClassTypeParameterName">
+            <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
+            <message key="name.invalidPattern"
+                     value="Class type name ''{0}'' must match pattern ''{1}''."/>
+        </module>
+        <module name="MethodTypeParameterName">
+            <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
+            <message key="name.invalidPattern"
+                     value="Method type name ''{0}'' must match pattern ''{1}''."/>
+        </module>
+        <module name="NoFinalizer"/>
+        <module name="GenericWhitespace">
+            <message key="ws.followed"
+                     value="GenericWhitespace ''{0}'' is followed by whitespace."/>
+            <message key="ws.preceded"
+                     value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
+            <message key="ws.illegalFollow"
+                     value="GenericWhitespace ''{0}'' should followed by whitespace."/>
+            <message key="ws.notPreceded"
+                     value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
+        </module>
+<!--        <module name="Indentation">-->
+<!--            <property name="basicOffset" value="2"/>-->
+<!--            <property name="braceAdjustment" value="0"/>-->
+<!--            <property name="caseIndent" value="2"/>-->
+<!--            <property name="throwsIndent" value="4"/>-->
+<!--            <property name="lineWrappingIndentation" value="4"/>-->
+<!--            <property name="arrayInitIndent" value="16"/>-->
+<!--        </module>-->
+<!--        <module name="OverloadMethodsDeclarationOrder"/>-->
+        <!-- Checks that our import order rules are followed. -->
+        <module name="CustomImportOrder">
+            <property name="specialImportsRegExp" value="alluxio"/>
+            <property name="customImportOrderRules" value="STATIC###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE"/>
+        </module>
+        <module name="MethodParamPad"/>
+        <module name="ParenPad">
+            <property name="option" value="nospace"/>
+        </module>
+        <module name="OperatorWrap">
+            <property name="option" value="NL"/>
+            <property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE,
+        LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/>
+        </module>
+        <module name="StaticVariableName">
+<!--            <property name="format" value="^s[A-Z][a-zA-Z0-9]*$"/>-->
+            <message key="name.invalidPattern"
+                     value="Static member name ''{0}'' must match pattern ''{1}''."/>
+        </module>
+        <module name="RegexpSinglelineJava">
+<!--            <property name="format" value="^\s*this\."/>-->
+<!--            <property name="message" value="keyword this is not needed"/>-->
+        </module>
+        <module name="MissingDeprecated"/>
+        <module name="EqualsHashCode"/>
+
+        <!-- Checks the Javadoc of a public method or constructor. Only applies to production code. -->
+        <module name="JavadocMethod">
+            <property name="id" value="ProductionScope"/>
+            <property name="scope" value="public"/>
+            <property name="allowMissingThrowsTags" value="true"/>
+            <property name="allowMissingPropertyJavadoc" value="true"/>
+<!--            <property name="allowMissingParamTags" value="true"/>-->
+<!--            <property name="allowMissingReturnTag" value="true"/>-->
+            <property name="tokens" value="ANNOTATION_FIELD_DEF"/>
+        </module>
+        <!-- Checks Javadoc comments for public class and interface definitions. Only applies to
+             production code -->
+<!--        <module name="JavadocType">-->
+<!--            <property name="id" value="ProductionScope"/>-->
+<!--            <property name="scope" value="public"/>-->
+<!--        </module>-->
+        <!-- Checks that Javadoc is properly formatted -->
+<!--        <module name="JavadocStyle"/>-->
+
+        <!-- Checks that there is no whitespace before various unary operators. -->
+        <module name="NoWhitespaceBefore">
+            <property name="tokens" value="POST_DEC, POST_INC"/>
+            <property name="severity" value="error"/>
+        </module>
+
+        <!-- Checks that there is no whitespace before dot and semicolon, except line-breaks. -->
+        <module name="NoWhitespaceBefore">
+            <property name="tokens" value="DOT, SEMI"/>
+            <property name="allowLineBreaks" value="true"/>
+            <property name="severity" value="error"/>
+        </module>
+
+        <!-- Checks that there is no whitespace after various unary operators. -->
+        <module name="NoWhitespaceAfter">
+            <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS"/>
+            <property name="severity" value="error"/>
+        </module>
+
+        <!-- Checks that there is whitespace after various tokens. -->
+        <module name="WhitespaceAfter"/>
+
+        <!-- Allows SuppressionCommentFilter to access module contents. -->
+<!--        <module name="FileContentsHolder"/>-->
+    </module>
+
+    <!-- always use Unix-style line separators -->
+    <module name="NewlineAtEndOfFile">
+        <property name="lineSeparator" value="lf"/>
+    </module>
+    <module name="RegexpSingleline">
+        <property name="format" value="\s+$"/>
+        <property name="message" value="Trailing whitespace found."/>
+        <property name="fileExtensions" value=".java"/>
+    </module>
+
+    <!-- Disables checkstyle for particular lines of codes. -->
+<!--    <module name="SuppressionCommentFilter">-->
+<!--        <property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>-->
+<!--        <property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>-->
+<!--    </module>-->
+</module>
diff --git a/manager/checkstyle/suppressions.xml b/manager/checkstyle/suppressions.xml
new file mode 100644
index 0000000..471fc2d
--- /dev/null
+++ b/manager/checkstyle/suppressions.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied. See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN"
+        "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+<suppressions>
+</suppressions>
\ No newline at end of file
diff --git a/manager/conf/manager.conf b/manager/conf/manager.conf
new file mode 100644
index 0000000..32c31d5
--- /dev/null
+++ b/manager/conf/manager.conf
@@ -0,0 +1,57 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# manager service database information
+#http port
+STUDIO_PORT=8080
+
+# The deployment depends on three data service types: mysql/h2/postgresql. MySQL is supported by default.
+MB_DB_TYPE=mysql
+
+# If h2 is used, only the data engine type needs to be configured, and the data will be directly saved
+# in the path of service operation in the form of file.
+# If you want to use mysql or postgresql, you need to configure the following connection information
+# Connection address
+#MB_DB_HOST=127.0.0.1
+
+# Connection port
+#MB_DB_PORT=3306
+
+# Connect access user
+#MB_DB_USER=root
+
+# Connection access user password
+#MB_DB_PASS=123456
+
+# Database accessed by the service(database)
+#MB_DB_DBNAME=manager
+
+# The name of the deployed service. The default is manager
+#DEPLOY_NAME=manager
+
+# The default port of the deployed nginx service is 8090. If nginx is not deployed, 8080 will be used directly
+# NGINX_PORT=8080
+
+# Operation and maintenance mailbox of the current Doris manage service instance
+#DS_ADMIN_EMAIL=
+
+# The name of the current Doris manage service instance is as follows by default and
+# can be customized and modified according to the actual situation
+# DS_SITE_NAME=Baidu-Doris-Manager
+
+# The language of the current Doris manage service instance is Chinese (zh) by default, and can support zh and en
+# DS_SITE_LOCALE=zh
diff --git a/manager/dm-agent/pom.xml b/manager/dm-agent/pom.xml
new file mode 100644
index 0000000..4ae3db5
--- /dev/null
+++ b/manager/dm-agent/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.doris</groupId>
+        <artifactId>doris-manager</artifactId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dm-agent</artifactId>
+    <packaging>jar</packaging>
+
+    <name>dm-agent</name>
+
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.doris</groupId>
+            <artifactId>dm-common</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.5</version>
+        </dependency>
+
+        <dependency>
+            <groupId>args4j</groupId>
+            <artifactId>args4j</artifactId>
+            <version>2.33</version>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/com.github.oshi/oshi-core -->
+        <dependency>
+            <groupId>com.github.oshi</groupId>
+            <artifactId>oshi-core</artifactId>
+            <version>4.0.0</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/DmAgentApplication.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/DmAgentApplication.java
new file mode 100644
index 0000000..9c3beb4
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/DmAgentApplication.java
@@ -0,0 +1,105 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.util.StdDateFormat;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.manager.agent.common.PropertiesUtil;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.agent.register.AgentHeartbeat;
+import org.apache.doris.manager.agent.register.ApplicationOption;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.system.ApplicationHome;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@SpringBootApplication
+@Slf4j
+public class DmAgentApplication {
+
+    public static void main(String[] args) {
+        ApplicationOption option = new ApplicationOption();
+        CmdLineParser parser = new CmdLineParser(option);
+        try {
+            parser.parseArgument(args);
+        } catch (CmdLineException e) {
+            e.printStackTrace();
+            return;
+        }
+
+        String agentPort = PropertiesUtil.getPropValue("server.port");
+        ApplicationHome applicationHome = new ApplicationHome(DmAgentApplication.class);
+        String agentInstallDir = applicationHome.getSource().getParentFile().getParentFile().toString();
+
+        boolean agentRegisterSuccess = AgentContext.register(option.agentIp, Integer.valueOf(agentPort), option.agentServer, agentInstallDir);
+        if (!agentRegisterSuccess) {
+            log.error("agent register fail");
+            return;
+        }
+
+        boolean serviceRegisterSuccess = ServiceContext.registerFromServer(option.agentServer, option.agentIp);
+        if (!serviceRegisterSuccess) {
+            log.error("service register fail");
+            return;
+        }
+
+        SpringApplication.run(DmAgentApplication.class, args);
+        AgentHeartbeat.start();
+    }
+
+    @Bean
+    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {
+            @Override
+            public Date parse(String source) {
+                try {
+                    return super.parse(source);
+                } catch (Exception e) {
+                    try {
+                        return new StdDateFormat().parse(source);
+                    } catch (ParseException e1) {
+                        throw new RuntimeException("Date format is illegal:" + e);
+                    }
+                }
+            }
+        };
+
+        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setDateFormat(dateFormat);
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        jsonConverter.setObjectMapper(objectMapper);
+        List<MediaType> list = new ArrayList<>();
+        list.add(MediaType.APPLICATION_JSON_UTF8);
+        jsonConverter.setSupportedMediaTypes(list);
+        return jsonConverter;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/CommandController.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/CommandController.java
new file mode 100644
index 0000000..840138b
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/CommandController.java
@@ -0,0 +1,58 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.api;
+
+import org.apache.doris.manager.agent.command.CommandFactory;
+import org.apache.doris.manager.agent.command.CommandResultService;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.common.domain.CommandRequest;
+import org.apache.doris.manager.common.domain.CommandResult;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.RResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Objects;
+
+@RestController
+@RequestMapping("/command")
+public class CommandController {
+
+    @PostMapping("/execute")
+    public RResult execute(@RequestBody CommandRequest commandRequest) {
+        if (Objects.isNull(CommandType.findByName(commandRequest.getCommandType()))) {
+            return RResult.error("Unkonwn command");
+        }
+        Task task = CommandFactory.get(commandRequest).setup().execute();
+        CommandResult commandResult = new CommandResult(task.getTaskResult());
+        return RResult.success(commandResult);
+    }
+
+    @GetMapping("/result")
+    public RResult commandResult(@RequestParam String taskId) {
+        CommandResult commandResult = CommandResultService.commandResult(taskId);
+        if (Objects.isNull(commandResult)) {
+            return RResult.error("Task not found");
+        }
+        return RResult.success(commandResult);
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/CommonControllder.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/CommonControllder.java
new file mode 100644
index 0000000..e22797e
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/CommonControllder.java
@@ -0,0 +1,87 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.api;
+
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.agent.service.BeService;
+import org.apache.doris.manager.agent.service.BrokerService;
+import org.apache.doris.manager.agent.service.FeService;
+import org.apache.doris.manager.agent.service.Service;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.common.domain.AgentRoleRegister;
+import org.apache.doris.manager.common.domain.RResult;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Objects;
+
+@RestController
+@RequestMapping
+public class CommonControllder {
+
+    @GetMapping("/context/agent")
+    public RResult agentContext() {
+        return RResult.success(AgentContext.getContext());
+    }
+
+    @GetMapping("/context/service")
+    public RResult serviceContext() {
+        return RResult.success(ServiceContext.getServiceMap());
+    }
+
+    @GetMapping("/service/config")
+    public RResult getServiceConfig(@RequestParam String serviceRole) {
+        Service service = ServiceContext.getServiceMap().get(ServiceRole.findByName(serviceRole));
+        if (Objects.isNull(service)) {
+            return RResult.error("service not installed");
+        }
+        return RResult.success(service.getConfig());
+    }
+
+    @PostMapping("/service/register")
+    public RResult registerService(@RequestBody AgentRoleRegister register) {
+        if (Objects.isNull(register.getHost()) || !register.getHost().equals(AgentContext.getAgentIp())) {
+            return RResult.error("param host is null or param host not equal agent ip");
+        }
+
+        Service service = ServiceContext.getServiceMap().get(ServiceRole.findByName(register.getRole()));
+        if (Objects.nonNull(service)) {
+            return RResult.error("service already registered");
+        }
+
+        if (ServiceRole.findByName(register.getRole()) == ServiceRole.FE) {
+            FeService feService = new FeService(register.getInstallDir());
+            ServiceContext.register(feService);
+        } else if (ServiceRole.findByName(register.getRole()) == ServiceRole.BE) {
+            BeService beService = new BeService(register.getInstallDir());
+            ServiceContext.register(beService);
+        } else if (ServiceRole.findByName(register.getRole()) == ServiceRole.BROKER) {
+            BrokerService brokerService = new BrokerService(register.getInstallDir());
+            ServiceContext.register(brokerService);
+        } else {
+            return RResult.error("unkown service role");
+        }
+
+        return RResult.success();
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/HardwareInfoController.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/HardwareInfoController.java
new file mode 100644
index 0000000..a6e80f3
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/HardwareInfoController.java
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.api;
+
+import org.apache.doris.manager.common.domain.HardwareInfo;
+import org.apache.doris.manager.common.domain.RResult;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import oshi.SystemInfo;
+import oshi.util.FormatUtil;
+
+/**
+ * hardware info
+ **/
+@RestController
+@RequestMapping("/hardware/view")
+public class HardwareInfoController {
+
+    @GetMapping
+    public RResult info() {
+        HardwareInfo hardwareInfo = new HardwareInfo();
+        SystemInfo systemInfo = new SystemInfo();
+        hardwareInfo.setCpu(systemInfo.getHardware().getProcessor().toString());
+        hardwareInfo.setTotalMemory(FormatUtil.formatBytes(systemInfo.getHardware().getMemory().getTotal()));
+        return RResult.success(hardwareInfo);
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/LogController.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/LogController.java
new file mode 100644
index 0000000..d523d15
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/api/LogController.java
@@ -0,0 +1,117 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.api;
+
+import com.google.common.base.Preconditions;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.agent.service.Service;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.common.domain.RResult;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * fe be log
+ **/
+@Slf4j
+@RestController
+@RequestMapping("/log")
+public class LogController {
+
+    private static final long WEB_LOG_BYTES = 1024 * 1024;  // 1MB
+
+    /**
+     * Obtain service logs according to type: fe.log/fe.out/be.log/be.out
+     */
+    @GetMapping
+    public RResult serviceLog(@RequestParam String type) {
+        String logPath = getLogPath(type);
+        Map<String, String> result = appendLogInfo(logPath);
+        return RResult.success(result);
+    }
+
+    /**
+     * Obtain task log
+     */
+    @GetMapping("/task")
+    public RResult taskLog(@RequestParam String taskId) {
+        String logPath = AgentContext.getAgentInstallDir() + AgentConstants.TASK_LOG_FILE_RELATIVE_PATH;
+        Map<String, String> result = appendLogInfo(logPath);
+        return RResult.success(result);
+    }
+
+    private String getLogPath(String type) {
+        Preconditions.checkArgument(StringUtils.isNotBlank(type), "type is required");
+        Map<ServiceRole, Service> serviceMap = ServiceContext.getServiceMap();
+        if (type.startsWith(ServiceRole.FE.name().toLowerCase())) {
+            return serviceMap.get(ServiceRole.FE).getInstallDir() + AgentConstants.LOG_FILE_RELATIVE_PATH + type;
+        } else if (type.startsWith(ServiceRole.BE.name().toLowerCase())) {
+            return serviceMap.get(ServiceRole.BE).getInstallDir() + AgentConstants.LOG_FILE_RELATIVE_PATH + type;
+        } else {
+            throw new AgentException("can not find this type log path:" + type);
+        }
+    }
+
+    private Map<String, String> appendLogInfo(String logPath) {
+        Map<String, String> map = new HashMap<>();
+        map.put("logPath", logPath);
+
+        RandomAccessFile raf = null;
+        try {
+            raf = new RandomAccessFile(logPath, "r");
+            long fileSize = raf.length();
+            long startPos = fileSize < WEB_LOG_BYTES ? 0L : fileSize - WEB_LOG_BYTES;
+            long webContentLength = fileSize < WEB_LOG_BYTES ? fileSize : WEB_LOG_BYTES;
+            raf.seek(startPos);
+            map.put("showingLast", webContentLength + " bytes of log");
+            StringBuilder sb = new StringBuilder();
+            String line = "";
+            while ((line = raf.readLine()) != null) {
+                sb.append(line).append("\n");
+            }
+            map.put("log", sb.toString());
+
+        } catch (FileNotFoundException e) {
+            map.put("error", "Couldn't open log file: " + logPath);
+        } catch (IOException e) {
+            map.put("error", "Failed to read log file: " + logPath);
+        } finally {
+            try {
+                if (raf != null) {
+                    raf.close();
+                }
+            } catch (IOException e) {
+                log.warn("fail to close log file: " + logPath, e);
+            }
+        }
+        return map;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeCommand.java
new file mode 100644
index 0000000..e00f9f2
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeCommand.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.service.Service;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.util.Objects;
+
+public abstract class BeCommand extends ExpandCommand {
+    @Override
+    public void beforeSetup() {
+        Service service = ServiceContext.getServiceMap().get(ServiceRole.BE);
+        if (Objects.isNull(service)) {
+            throw new AgentException("service be not installed or register");
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeInstallCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeInstallCommand.java
new file mode 100644
index 0000000..e025c39
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeInstallCommand.java
@@ -0,0 +1,112 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.agent.service.BeService;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.agent.task.TaskHook;
+import org.apache.doris.manager.common.domain.BeInstallCommandRequestBody;
+import org.apache.doris.manager.common.domain.CommandType;
+
+import java.util.Objects;
+
+public class BeInstallCommand extends Command {
+    private BeInstallCommandRequestBody requestBody;
+
+    public BeInstallCommand(BeInstallCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        validCommand();
+
+        if (requestBody.getInstallDir().endsWith("/")) {
+            requestBody.setInstallDir(requestBody.getInstallDir().substring(0, requestBody.getInstallDir().length() - 1));
+        }
+
+        BeInstallTaskDesc taskDesc = new BeInstallTaskDesc();
+
+        String scriptCmd = AgentConstants.BASH_BIN;
+        scriptCmd += AgentContext.getAgentInstallDir() + "/bin/install_be.sh ";
+        scriptCmd += " --installDir " + requestBody.getInstallDir();
+        scriptCmd += " --url " + requestBody.getPackageUrl();
+        taskDesc.setScriptCmd(scriptCmd);
+        taskDesc.setInstallDir(requestBody.getInstallDir());
+        taskDesc.setCreateBeStorageDir(requestBody.isMkBeStorageDir());
+        return new ScriptTask(taskDesc, new BeInstallTaskHook());
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.INSTALL_BE;
+    }
+
+    private void validCommand() {
+        if (Objects.isNull(requestBody.getInstallDir()) || Objects.isNull(requestBody.getPackageUrl())) {
+            throw new AgentException("required parameters are missing in body param");
+        }
+
+        if (!requestBody.getInstallDir().startsWith("/")) {
+            throw new AgentException("the installation path must use an absolute path");
+        }
+    }
+
+    private static class BeInstallTaskDesc extends ScriptTaskDesc {
+        private String installDir;
+        private boolean createBeStorageDir;
+
+        public String getInstallDir() {
+            return installDir;
+        }
+
+        public void setInstallDir(String installDir) {
+            this.installDir = installDir;
+        }
+
+        public boolean isCreateBeStorageDir() {
+            return createBeStorageDir;
+        }
+
+        public void setCreateBeStorageDir(boolean createBeStorageDir) {
+            this.createBeStorageDir = createBeStorageDir;
+        }
+    }
+
+    private static class BeInstallTaskHook extends TaskHook<BeInstallTaskDesc> {
+        @Override
+        public void onSuccess(BeInstallTaskDesc taskDesc) {
+            BeService beService = new BeService(taskDesc.getInstallDir());
+            ServiceContext.register(beService);
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeStartCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeStartCommand.java
new file mode 100644
index 0000000..3a811da
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeStartCommand.java
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.common.domain.BeStartCommandRequestBody;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.util.Objects;
+
+public class BeStartCommand extends BeCommand {
+    private BeStartCommandRequestBody requestBody;
+
+    public BeStartCommand(BeStartCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        String scriptCmd = "";
+        ScriptTaskDesc taskDesc = new ScriptTaskDesc();
+        if (Objects.nonNull(requestBody) && requestBody.isStopBeforeStart()) {
+            scriptCmd += AgentConstants.BASH_BIN;
+            scriptCmd += ServiceContext.getServiceMap().get(ServiceRole.BE).getInstallDir() + "/bin/stop_be.sh ;";
+        }
+        scriptCmd += "cd " + ServiceContext.getServiceMap().get(ServiceRole.BE).getInstallDir() + " && ";
+        scriptCmd += AgentConstants.BASH_BIN + "./bin/start_be.sh --daemon";
+        taskDesc.setScriptCmd(scriptCmd);
+        return new ScriptTask(taskDesc);
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.START_BE;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeStopCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeStopCommand.java
new file mode 100644
index 0000000..f336c94
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BeStopCommand.java
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+public class BeStopCommand extends BeCommand {
+    @Override
+    public Task setupTask() {
+        ScriptTaskDesc taskDesc = new ScriptTaskDesc();
+
+        String scriptCmd = AgentConstants.BASH_BIN;
+        scriptCmd += ServiceContext.getServiceMap().get(ServiceRole.BE).getInstallDir() + "/bin/stop_be.sh ";
+        taskDesc.setScriptCmd(scriptCmd);
+        return new ScriptTask(taskDesc);
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.STOP_BE;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerCommand.java
new file mode 100644
index 0000000..06ffd27
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerCommand.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.service.Service;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.util.Objects;
+
+public abstract class BrokerCommand extends ExpandCommand {
+    @Override
+    void beforeSetup() {
+        Service service = ServiceContext.getServiceMap().get(ServiceRole.BROKER);
+        if (Objects.isNull(service)) {
+            throw new AgentException("service broker not installed or register");
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerInstallCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerInstallCommand.java
new file mode 100644
index 0000000..b30491d
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerInstallCommand.java
@@ -0,0 +1,103 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.agent.service.BrokerService;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.agent.task.TaskHook;
+import org.apache.doris.manager.common.domain.BrokerInstallCommandRequestBody;
+import org.apache.doris.manager.common.domain.CommandType;
+
+import java.util.Objects;
+
+public class BrokerInstallCommand extends Command {
+    private BrokerInstallCommandRequestBody requestBody;
+
+    public BrokerInstallCommand(BrokerInstallCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        validCommand();
+
+        if (requestBody.getInstallDir().endsWith("/")) {
+            requestBody.setInstallDir(requestBody.getInstallDir().substring(0, requestBody.getInstallDir().length() - 1));
+        }
+
+        BrokerInstallTaskDesc taskDesc = new BrokerInstallTaskDesc();
+
+        String scriptCmd = AgentConstants.BASH_BIN;
+        scriptCmd += AgentContext.getAgentInstallDir() + "/bin/install_broker.sh ";
+        scriptCmd += " --installDir " + requestBody.getInstallDir();
+        scriptCmd += " --url " + requestBody.getPackageUrl();
+
+        taskDesc.setScriptCmd(scriptCmd);
+        taskDesc.setInstallDir(requestBody.getInstallDir());
+        return new ScriptTask(taskDesc, new BrokerInstallTaskHook());
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.INSTALL_BROKER;
+    }
+
+    private void validCommand() {
+        if (Objects.isNull(requestBody.getInstallDir()) || Objects.isNull(requestBody.getPackageUrl())) {
+            throw new AgentException("required parameters are missing in body param");
+        }
+
+        if (!requestBody.getInstallDir().startsWith("/")) {
+            throw new AgentException("the installation path must use an absolute path");
+        }
+    }
+
+    private static class BrokerInstallTaskDesc extends ScriptTaskDesc {
+        private String installDir;
+
+        public String getInstallDir() {
+            return installDir;
+        }
+
+        public void setInstallDir(String installDir) {
+            this.installDir = installDir;
+        }
+    }
+
+    private static class BrokerInstallTaskHook extends TaskHook<BrokerInstallTaskDesc> {
+        @Override
+        public void onSuccess(BrokerInstallTaskDesc taskDesc) {
+            BrokerService brokerService = new BrokerService(taskDesc.getInstallDir());
+            ServiceContext.register(brokerService);
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerStartCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerStartCommand.java
new file mode 100644
index 0000000..9ac62e3
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerStartCommand.java
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.common.domain.BrokerStartCommandRequestBody;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.util.Objects;
+
+public class BrokerStartCommand extends BrokerCommand {
+    private BrokerStartCommandRequestBody requestBody;
+
+    public BrokerStartCommand(BrokerStartCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        String scriptCmd = "";
+        ScriptTaskDesc taskDesc = new ScriptTaskDesc();
+        if (Objects.nonNull(requestBody) && requestBody.isStopBeforeStart()) {
+            scriptCmd += AgentConstants.BASH_BIN;
+            scriptCmd += ServiceContext.getServiceMap().get(ServiceRole.BROKER).getInstallDir() + "/bin/stop_broker.sh ;";
+        }
+
+        scriptCmd += AgentConstants.BASH_BIN;
+        scriptCmd += ServiceContext.getServiceMap().get(ServiceRole.BROKER).getInstallDir() + "/bin/start_broker.sh --daemon";
+        taskDesc.setScriptCmd(scriptCmd);
+        return new ScriptTask(taskDesc);
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.START_BROKER;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerStopCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerStopCommand.java
new file mode 100644
index 0000000..960ad88
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/BrokerStopCommand.java
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+public class BrokerStopCommand extends BrokerCommand {
+    @Override
+    public Task setupTask() {
+        ScriptTaskDesc taskDesc = new ScriptTaskDesc();
+
+        String scriptCmd = AgentConstants.BASH_BIN;
+        scriptCmd += ServiceContext.getServiceMap().get(ServiceRole.BROKER).getInstallDir() + "/bin/stop_broker.sh ";
+        taskDesc.setScriptCmd(scriptCmd);
+        return new ScriptTask(taskDesc);
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.STOP_BROKER;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/Command.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/Command.java
new file mode 100644
index 0000000..afbdde2
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/Command.java
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.common.domain.CommandType;
+
+public abstract class Command {
+    protected CommandType commandType;
+    private Task task;
+    private ITaskHandlerFactory handlerFactory;
+
+    public Command setup() {
+        task = setupTask();
+        commandType = setupCommandType();
+        task.getTaskDesc().setTaskName(commandType.name());
+        handlerFactory = setupTaskHandlerFactory();
+        return this;
+    }
+
+    public abstract Task setupTask();
+
+    public abstract CommandType setupCommandType();
+
+    public abstract ITaskHandlerFactory setupTaskHandlerFactory();
+
+    public Task execute() {
+        handlerFactory.createTaskHandler().handle(task);
+        return task;
+    }
+
+    public ITaskHandlerFactory getHandlerFactory() {
+        return handlerFactory;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/CommandFactory.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/CommandFactory.java
new file mode 100644
index 0000000..5423a1f
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/CommandFactory.java
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.common.domain.BeInstallCommandRequestBody;
+import org.apache.doris.manager.common.domain.BeStartCommandRequestBody;
+import org.apache.doris.manager.common.domain.BrokerInstallCommandRequestBody;
+import org.apache.doris.manager.common.domain.BrokerStartCommandRequestBody;
+import org.apache.doris.manager.common.domain.CommandRequest;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.FeInstallCommandRequestBody;
+import org.apache.doris.manager.common.domain.FeStartCommandRequestBody;
+import org.apache.doris.manager.common.domain.WriteBeConfCommandRequestBody;
+import org.apache.doris.manager.common.domain.WriteBrokerConfCommandRequestBody;
+import org.apache.doris.manager.common.domain.WriteFeConfCommandRequestBody;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Base64;
+import java.util.Objects;
+
+public class CommandFactory {
+    public static Command get(CommandRequest commandRequest) {
+        String body = null;
+        if (Objects.nonNull(commandRequest.getBody())) {
+            try {
+                body = URLDecoder.decode(commandRequest.getBody(), "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+                throw new AgentException(e.getMessage());
+            }
+        }
+
+        switch (CommandType.valueOf(commandRequest.getCommandType())) {
+            case INSTALL_FE:
+                validBody(body);
+                return new FeInstallCommand(JSON.parseObject(body, FeInstallCommandRequestBody.class));
+            case INSTALL_BE:
+                validBody(body);
+                return new BeInstallCommand(JSON.parseObject(body, BeInstallCommandRequestBody.class));
+            case INSTALL_BROKER:
+                validBody(body);
+                return new BrokerInstallCommand(JSON.parseObject(body, BrokerInstallCommandRequestBody.class));
+            case START_FE:
+                return new FeStartCommand(JSON.parseObject(body, FeStartCommandRequestBody.class));
+            case STOP_FE:
+                return new FeStopCommand();
+            case START_BE:
+                return new BeStartCommand(JSON.parseObject(body, BeStartCommandRequestBody.class));
+            case STOP_BE:
+                return new BeStopCommand();
+            case START_BROKER:
+                return new BrokerStartCommand(JSON.parseObject(body, BrokerStartCommandRequestBody.class));
+            case STOP_BROKER:
+                return new BrokerStopCommand();
+            case WRITE_FE_CONF:
+                validBody(body);
+                WriteFeConfCommandRequestBody writeFeConfCommandRequestBody = JSON.parseObject(body, WriteFeConfCommandRequestBody.class);
+                Base64.Decoder decoder = Base64.getDecoder();
+                try {
+                    writeFeConfCommandRequestBody.setContent(new String(decoder.decode(writeFeConfCommandRequestBody.getContent()), "UTF-8"));
+                } catch (UnsupportedEncodingException e) {
+                    e.printStackTrace();
+                }
+                return new WriteFeConfCommand(writeFeConfCommandRequestBody);
+            case WRITE_BE_CONF:
+                validBody(body);
+                WriteBeConfCommandRequestBody writeBeConfCommandRequestBody = JSON.parseObject(body, WriteBeConfCommandRequestBody.class);
+                Base64.Decoder decoder2 = Base64.getDecoder();
+                try {
+                    writeBeConfCommandRequestBody.setContent(new String(decoder2.decode(writeBeConfCommandRequestBody.getContent()), "UTF-8"));
+                } catch (UnsupportedEncodingException e) {
+                    e.printStackTrace();
+                }
+                return new WriteBeConfCommand(writeBeConfCommandRequestBody);
+            case WRITE_BROKER_CONF:
+                validBody(body);
+                WriteBrokerConfCommandRequestBody writeBrokerConfCommandRequestBody = JSON.parseObject(body, WriteBrokerConfCommandRequestBody.class);
+                Base64.Decoder decoder3 = Base64.getDecoder();
+                try {
+                    writeBrokerConfCommandRequestBody.setContent(new String(decoder3.decode(writeBrokerConfCommandRequestBody.getContent()), "UTF-8"));
+                } catch (UnsupportedEncodingException e) {
+                    e.printStackTrace();
+                }
+                return new WriteBrokerConfCommand(writeBrokerConfCommandRequestBody);
+            default:
+                throw new AgentException("unkown CommandType");
+        }
+    }
+
+    private static void validBody(String body) {
+        if (Objects.isNull(body) || body.length() == 0) {
+            throw new AgentException("param body can not be empty");
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/CommandResultService.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/CommandResultService.java
new file mode 100644
index 0000000..5c175dc
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/CommandResultService.java
@@ -0,0 +1,123 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.LRU;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskContext;
+import org.apache.doris.manager.common.domain.CommandResult;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.apache.doris.manager.common.domain.TaskResult;
+import org.apache.doris.manager.common.domain.TaskState;
+
+import java.util.Objects;
+
+public class CommandResultService {
+    private static LRU<String, Integer> taskFinalStatus = new LRU<>(AgentConstants.COMMAND_HISTORY_SAVE_MAX_COUNT);
+
+    public static CommandResult commandResult(String taskId) {
+        if (Objects.isNull(TaskContext.getTaskByTaskId(taskId))) {
+            return null;
+        }
+
+        Task task = TaskContext.getTaskByTaskId(taskId);
+        CommandResult commandResult = new CommandResult(task.getTaskResult());
+
+        switch (CommandType.valueOf(task.getTaskDesc().getTaskName())) {
+            case INSTALL_FE:
+            case INSTALL_BE:
+            case WRITE_BE_CONF:
+            case WRITE_FE_CONF:
+            case WRITE_BROKER_CONF:
+            case INSTALL_BROKER:
+                return commandResult;
+            case START_FE:
+                return fetchCommandResult(task, CommandType.START_FE);
+            case STOP_FE:
+                return fetchCommandResult(task, CommandType.STOP_FE);
+            case START_BE:
+                return fetchCommandResult(task, CommandType.START_BE);
+            case STOP_BE:
+                return fetchCommandResult(task, CommandType.STOP_BE);
+            case START_BROKER:
+                return fetchCommandResult(task, CommandType.START_BROKER);
+            case STOP_BROKER:
+                return fetchCommandResult(task, CommandType.STOP_BROKER);
+            default:
+                return null;
+        }
+    }
+
+    private static CommandResult fetchCommandResult(Task task, CommandType commandType) {
+        if (Objects.isNull(task.getTaskResult().getRetCode()) || task.getTaskResult().getRetCode() != 0) {
+            return new CommandResult(task.getTaskResult());
+        }
+
+        TaskResult tmpTaskResult = new TaskResult(task.getTaskResult());
+
+        Integer finalStatus = taskFinalStatus.get(task.getTaskId());
+        if (Objects.nonNull(finalStatus)) {
+            tmpTaskResult.setTaskState(TaskState.FINISHED);
+            tmpTaskResult.setRetCode(finalStatus);
+            return new CommandResult(tmpTaskResult);
+        }
+
+        if (Objects.isNull(task.getTaskResult().getStartTime())
+                || task.getTaskResult().getStartTime().getTime() + AgentConstants.COMMAND_EXECUTE_DETECT_DURATION_MILSECOND > System.currentTimeMillis()) {
+            tmpTaskResult.setTaskState(TaskState.RUNNING);
+            tmpTaskResult.setRetCode(AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE);
+            return new CommandResult(tmpTaskResult);
+        }
+
+        int retCode = AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE;
+        Boolean health = false;
+        if (CommandType.START_FE == commandType) {
+            health = ServiceContext.getServiceMap().get(ServiceRole.FE).processExist();
+            retCode = health ? AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE : AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE;
+        } else if (CommandType.STOP_FE == commandType) {
+            health = ServiceContext.getServiceMap().get(ServiceRole.FE).processExist();
+            retCode = !health ? AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE : AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE;
+        } else if (CommandType.START_BE == commandType) {
+            health = ServiceContext.getServiceMap().get(ServiceRole.BE).processExist();
+            retCode = health ? AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE : AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE;
+        } else if (CommandType.STOP_BE == commandType) {
+            health = ServiceContext.getServiceMap().get(ServiceRole.BE).processExist();
+            retCode = !health ? AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE : AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE;
+        } else if (CommandType.START_BROKER == commandType) {
+            health = ServiceContext.getServiceMap().get(ServiceRole.BROKER).processExist();
+            retCode = health ? AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE : AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE;
+        } else if (CommandType.STOP_BROKER == commandType) {
+            health = ServiceContext.getServiceMap().get(ServiceRole.BROKER).processExist();
+            retCode = !health ? AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE : AgentConstants.COMMAND_EXECUTE_UNHEALTH_CODE;
+        }
+
+        if (health && (CommandType.START_FE == commandType || CommandType.START_BE == commandType || CommandType.START_BROKER == commandType)) {
+            taskFinalStatus.put(task.getTaskId(), AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE);
+        }
+        if (!health && (CommandType.STOP_FE == commandType || CommandType.STOP_BE == commandType || CommandType.STOP_BROKER == commandType)) {
+            taskFinalStatus.put(task.getTaskId(), AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE);
+        }
+
+        tmpTaskResult.setRetCode(retCode);
+        tmpTaskResult.setTaskState(TaskState.FINISHED);
+        return new CommandResult(tmpTaskResult);
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/ExpandCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/ExpandCommand.java
new file mode 100644
index 0000000..f0b6815
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/ExpandCommand.java
@@ -0,0 +1,28 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+public abstract class ExpandCommand extends Command {
+    @Override
+    public Command setup() {
+        beforeSetup();
+        return super.setup();
+    }
+
+    abstract void beforeSetup();
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeCommand.java
new file mode 100644
index 0000000..d1c3c10
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeCommand.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.service.Service;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.util.Objects;
+
+public abstract class FeCommand extends ExpandCommand {
+    @Override
+    public void beforeSetup() {
+        Service service = ServiceContext.getServiceMap().get(ServiceRole.FE);
+        if (Objects.isNull(service)) {
+            throw new AgentException("service fe not installed or register");
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeInstallCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeInstallCommand.java
new file mode 100644
index 0000000..aa2c7e3
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeInstallCommand.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.agent.service.FeService;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.agent.task.TaskHook;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.FeInstallCommandRequestBody;
+
+import java.util.Objects;
+
+public class FeInstallCommand extends Command {
+    private FeInstallCommandRequestBody requestBody;
+
+    public FeInstallCommand(FeInstallCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        validCommand();
+
+        if (requestBody.getInstallDir().endsWith("/")) {
+            requestBody.setInstallDir(requestBody.getInstallDir().substring(0, requestBody.getInstallDir().length() - 1));
+        }
+
+        FeInstallTaskDesc taskDesc = new FeInstallTaskDesc();
+
+        String scriptCmd = AgentConstants.BASH_BIN;
+        scriptCmd += AgentContext.getAgentInstallDir() + "/bin/install_fe.sh ";
+        scriptCmd += " --installDir " + requestBody.getInstallDir();
+        scriptCmd += " --url " + requestBody.getPackageUrl();
+        if (requestBody.getMkFeMetadir()) {
+            taskDesc.setCreateMetaDir(true);
+        }
+
+        taskDesc.setScriptCmd(scriptCmd);
+        taskDesc.setInstallDir(requestBody.getInstallDir());
+        return new ScriptTask(taskDesc, new FeInstallTaskHook());
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.INSTALL_FE;
+    }
+
+    private void validCommand() {
+        if (Objects.isNull(requestBody.getInstallDir()) || Objects.isNull(requestBody.getPackageUrl())) {
+            throw new AgentException("required parameters are missing in body param");
+        }
+
+        if (!requestBody.getInstallDir().startsWith("/")) {
+            throw new AgentException("the installation path must use an absolute path");
+        }
+    }
+
+    private static class FeInstallTaskDesc extends ScriptTaskDesc {
+        private String installDir;
+        private boolean createMetaDir;
+
+        public String getInstallDir() {
+            return installDir;
+        }
+
+        public void setInstallDir(String installDir) {
+            this.installDir = installDir;
+        }
+
+        public boolean isCreateMetaDir() {
+            return createMetaDir;
+        }
+
+        public void setCreateMetaDir(boolean createMetaDir) {
+            this.createMetaDir = createMetaDir;
+        }
+    }
+
+    private static class FeInstallTaskHook extends TaskHook<FeInstallTaskDesc> {
+        @Override
+        public void onSuccess(FeInstallTaskDesc taskDesc) {
+            FeService feService = new FeService(taskDesc.getInstallDir());
+            ServiceContext.register(feService);
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeStartCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeStartCommand.java
new file mode 100644
index 0000000..d6299fe
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeStartCommand.java
@@ -0,0 +1,70 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.FeStartCommandRequestBody;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.util.Objects;
+
+public class FeStartCommand extends FeCommand {
+    private FeStartCommandRequestBody requestBody;
+
+    public FeStartCommand(FeStartCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        ScriptTaskDesc taskDesc = new ScriptTaskDesc();
+        String scriptCmd = "";
+
+        if (Objects.nonNull(requestBody) && requestBody.isStopBeforeStart()) {
+            scriptCmd += AgentConstants.BASH_BIN;
+            scriptCmd += ServiceContext.getServiceMap().get(ServiceRole.FE).getInstallDir() + "/bin/stop_fe.sh ; ";
+        }
+
+        scriptCmd += "cd " + ServiceContext.getServiceMap().get(ServiceRole.FE).getInstallDir() + " && ";
+        scriptCmd += AgentConstants.BASH_BIN + "./bin/start_fe.sh ";
+        if (Objects.nonNull(requestBody) && Objects.nonNull(requestBody.getHelpHostPort()) && requestBody.getHelpHostPort().length() > 0) {
+            scriptCmd += " --help " + requestBody.getHelpHostPort();
+        }
+        scriptCmd += " --daemon";
+        taskDesc.setScriptCmd(scriptCmd);
+        return new ScriptTask(taskDesc);
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.START_FE;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeStopCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeStopCommand.java
new file mode 100644
index 0000000..f20fd42
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/FeStopCommand.java
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.ScriptTask;
+import org.apache.doris.manager.agent.task.ScriptTaskDesc;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+public class FeStopCommand extends FeCommand {
+    @Override
+    public Task setupTask() {
+        ScriptTaskDesc taskDesc = new ScriptTaskDesc();
+
+        String scriptCmd = AgentConstants.BASH_BIN;
+        scriptCmd += ServiceContext.getServiceMap().get(ServiceRole.FE).getInstallDir() + "/bin/stop_fe.sh ";
+        taskDesc.setScriptCmd(scriptCmd);
+        return new ScriptTask(taskDesc);
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.STOP_FE;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteBeConfCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteBeConfCommand.java
new file mode 100644
index 0000000..df4d183
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteBeConfCommand.java
@@ -0,0 +1,103 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.service.BeService;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskDesc;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.agent.task.TaskHook;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.apache.doris.manager.common.domain.WriteBeConfCommandRequestBody;
+
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Objects;
+
+public class WriteBeConfCommand extends BeCommand {
+    private WriteBeConfCommandRequestBody requestBody;
+
+    public WriteBeConfCommand(WriteBeConfCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        if (Objects.isNull(requestBody.getContent())) {
+            throw new AgentException("configuration content cannot be empty");
+        }
+
+        WriteBeConfTaskDesc desc = new WriteBeConfTaskDesc();
+        desc.setCreateStorageDir(requestBody.isCreateStorageDir());
+        WriteBeConfTaskHook hook = new WriteBeConfTaskHook();
+
+        return new Task<TaskDesc>(desc, hook) {
+            @Override
+            protected int execute() throws IOException {
+                try (FileOutputStream fos = new FileOutputStream(ServiceContext.getServiceMap().get(ServiceRole.BE).getConfigFilePath());
+                     OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
+                     BufferedWriter bw = new BufferedWriter(osw)) {
+                    bw.write(requestBody.getContent());
+                    bw.flush();
+                }
+                return 0;
+            }
+        };
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.WRITE_BE_CONF;
+    }
+
+    private static class WriteBeConfTaskDesc extends TaskDesc {
+        private boolean createStorageDir;
+
+        public boolean isCreateStorageDir() {
+            return createStorageDir;
+        }
+
+        public void setCreateStorageDir(boolean createStorageDir) {
+            this.createStorageDir = createStorageDir;
+        }
+    }
+
+    private static class WriteBeConfTaskHook extends TaskHook<WriteBeConfTaskDesc> {
+        @Override
+        public void onSuccess(WriteBeConfTaskDesc taskDesc) {
+            BeService service = (BeService) ServiceContext.getServiceMap().get(ServiceRole.BE);
+            service.load();
+
+            if (taskDesc.isCreateStorageDir()) {
+                service.createStrorageDir();
+            }
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteBrokerConfCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteBrokerConfCommand.java
new file mode 100644
index 0000000..3ecc523
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteBrokerConfCommand.java
@@ -0,0 +1,87 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.service.BrokerService;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskDesc;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.agent.task.TaskHook;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.apache.doris.manager.common.domain.WriteBrokerConfCommandRequestBody;
+
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Objects;
+
+public class WriteBrokerConfCommand extends BrokerCommand {
+    private WriteBrokerConfCommandRequestBody requestBody;
+
+    public WriteBrokerConfCommand(WriteBrokerConfCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        if (Objects.isNull(requestBody.getContent())) {
+            throw new AgentException("configuration content cannot be empty");
+        }
+
+        TaskDesc desc = new TaskDesc();
+        WriteBrokerConfTaskHook hook = new WriteBrokerConfTaskHook();
+
+        return new Task<TaskDesc>(desc, hook) {
+            @Override
+            protected int execute() throws IOException {
+                try (FileOutputStream fos = new FileOutputStream(ServiceContext.getServiceMap().get(ServiceRole.BROKER).getConfigFilePath());
+                     OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
+                     BufferedWriter bw = new BufferedWriter(osw)) {
+                    bw.write(requestBody.getContent());
+                    bw.flush();
+                }
+                return AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE;
+            }
+        };
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.WRITE_BROKER_CONF;
+    }
+
+    private static class WriteBrokerConfTaskHook extends TaskHook<TaskDesc> {
+        @Override
+        public void onSuccess(TaskDesc taskDesc) {
+            BrokerService service = (BrokerService) ServiceContext.getServiceMap().get(ServiceRole.BROKER);
+            service.load();
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteFeConfCommand.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteFeConfCommand.java
new file mode 100644
index 0000000..eca53ba
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/command/WriteFeConfCommand.java
@@ -0,0 +1,103 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.command;
+
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.service.FeService;
+import org.apache.doris.manager.agent.service.ServiceContext;
+import org.apache.doris.manager.agent.task.ITaskHandlerFactory;
+import org.apache.doris.manager.agent.task.QueuedTaskHandlerFactory;
+import org.apache.doris.manager.agent.task.Task;
+import org.apache.doris.manager.agent.task.TaskDesc;
+import org.apache.doris.manager.agent.task.TaskHandlerFactory;
+import org.apache.doris.manager.agent.task.TaskHook;
+import org.apache.doris.manager.common.domain.CommandType;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.apache.doris.manager.common.domain.WriteFeConfCommandRequestBody;
+
+import java.io.BufferedWriter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.Objects;
+
+public class WriteFeConfCommand extends FeCommand {
+    private WriteFeConfCommandRequestBody requestBody;
+
+    public WriteFeConfCommand(WriteFeConfCommandRequestBody requestBody) {
+        this.requestBody = requestBody;
+    }
+
+    @Override
+    public Task setupTask() {
+        if (Objects.isNull(requestBody.getContent())) {
+            throw new AgentException("configuration content cannot be empty");
+        }
+
+        WriteFeConfTaskDesc desc = new WriteFeConfTaskDesc();
+        desc.setCreateMetaDir(requestBody.isCreateMetaDir());
+
+        WriteFeConfTaskHook hook = new WriteFeConfTaskHook();
+
+        return new Task<TaskDesc>(desc, hook) {
+            @Override
+            protected int execute() throws IOException {
+                try (FileOutputStream fos = new FileOutputStream(ServiceContext.getServiceMap().get(ServiceRole.FE).getConfigFilePath());
+                     OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
+                     BufferedWriter bw = new BufferedWriter(osw)) {
+                    bw.write(requestBody.getContent());
+                    bw.flush();
+                }
+                return 0;
+            }
+        };
+    }
+
+    @Override
+    public ITaskHandlerFactory setupTaskHandlerFactory() {
+        return TaskHandlerFactory.getTaskHandlerFactory(QueuedTaskHandlerFactory.class);
+    }
+
+    @Override
+    public CommandType setupCommandType() {
+        return CommandType.WRITE_FE_CONF;
+    }
+
+    private static class WriteFeConfTaskDesc extends TaskDesc {
+        private boolean isCreateMetaDir;
+
+        public boolean isCreateMetaDir() {
+            return isCreateMetaDir;
+        }
+
+        public void setCreateMetaDir(boolean createMetaDir) {
+            isCreateMetaDir = createMetaDir;
+        }
+    }
+
+    private static class WriteFeConfTaskHook extends TaskHook<WriteFeConfTaskDesc> {
+        @Override
+        public void onSuccess(WriteFeConfTaskDesc taskDesc) {
+            FeService service = (FeService) ServiceContext.getServiceMap().get(ServiceRole.FE);
+            service.load();
+            if (taskDesc.isCreateMetaDir()) {
+                service.createMetaDir();
+            }
+        }
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/common/AgentConstants.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/common/AgentConstants.java
new file mode 100644
index 0000000..e4756a9
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/common/AgentConstants.java
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.common;
+
+public class AgentConstants {
+    public static final int COMMAND_EXECUTE_SUCCESS_CODE = 0;
+    public static final int COMMAND_EXECUTE_UNHEALTH_CODE = -10;
+    public static final int COMMAND_EXECUTE_DETECT_DURATION_MILSECOND = 10000;
+
+    public static final int COMMAND_HISTORY_SAVE_MAX_COUNT = 100;
+
+    public static final String BASH_BIN = " /bin/bash ";
+
+    public static final String FE_CONFIG_KEY_META_DIR = "meta_dir";
+    public static final String BE_CONFIG_KEY_STORAGE_DIR = "storage_root_path";
+    public static final String FE_CONFIG_KEY_HTTP_PORT = "http_port";
+    public static final String BE_CONFIG_KEY_HTTP_PORT = "webserver_port";
+    public static final String BROKER_CONFIG_KEY_IPC_PORT = "broker_ipc_port";
+
+    public static final String FE_CONFIG_FILE_RELATIVE_PATH = "/conf/fe.conf";
+    public static final String BE_CONFIG_FILE_RELATIVE_PATH = "/conf/be.conf";
+    public static final String BROKER_CONFIG_FILE_RELATIVE_PATH = "/conf/apache_hdfs_broker.conf";
+
+    public static final String LOG_FILE_RELATIVE_PATH = "/log/";
+    public static final String TASK_LOG_FILE_RELATIVE_PATH = "/log/task.log";
+
+    public static final int TASK_ERROR_CODE_DEFAULT = -501;
+    public static final int TASK_ERROR_CODE_EXCEPTION = -502;
+
+    public static final String LOG_TYPE_TASK = "TASK_LOG";
+
+    public static final String PROCESS_KEYWORD_FE = "org.apache.doris.PaloFe";
+    public static final String PROCESS_KEYWORD_BE = "palo_be";
+    public static final String PROCESS_KEYWORD_BROKER = "org.apache.doris.broker.hdfs.BrokerBootstrap";
+
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/common/PropertiesUtil.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/common/PropertiesUtil.java
new file mode 100644
index 0000000..6ca37d1
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/common/PropertiesUtil.java
@@ -0,0 +1,51 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.common;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Properties;
+
+@Slf4j
+public class PropertiesUtil {
+
+    private static final String DEFAULT_PROPERTIES = "/application.properties";
+
+    /**
+     * get properties key
+     *
+     * @param propKey
+     * @return
+     */
+    public static String getPropValue(String propKey) {
+        try {
+            Properties props = new Properties();
+            InputStream inputStream = PropertiesUtil.class.getResourceAsStream(DEFAULT_PROPERTIES);
+            BufferedReader bf = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+            props.load(bf);
+            return props.getProperty(propKey);
+        } catch (IOException e) {
+            log.error("get propKey error:", e);
+        }
+        return null;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/exception/AgentException.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/exception/AgentException.java
new file mode 100644
index 0000000..6012028
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/exception/AgentException.java
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.exception;
+
+public class AgentException extends RuntimeException {
+    private static final long serialVersionUID = -1L;
+    private static final Integer DEAFULT_EXCEPTION_STATUS = 500;
+    private int status;
+
+    public AgentException(String message) {
+        this(message, DEAFULT_EXCEPTION_STATUS);
+    }
+
+    public AgentException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public AgentException(String message, int status) {
+        super(message);
+        this.status = status;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/exception/GlobalExceptionHandler.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..67db791
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/exception/GlobalExceptionHandler.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.exception;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.manager.common.domain.RResult;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler(AgentException.class)
+    public RResult handleException(AgentException exception) {
+        log.error(exception.getMessage(), exception);
+        return RResult.error(exception.getStatus(), exception.getMessage());
+    }
+
+    @ExceptionHandler(Throwable.class)
+    public RResult javaExceptionHandler(Exception ex) {
+        log.error("agent error ", ex);
+        return RResult.error(5000, "agent error");
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/AgentContext.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/AgentContext.java
new file mode 100644
index 0000000..95d17a5
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/AgentContext.java
@@ -0,0 +1,91 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.register;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.doris.manager.agent.util.Request;
+import org.apache.doris.manager.common.domain.RResult;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class AgentContext {
+    private static String agentIp = null;
+    private static Integer agentPort = null;
+    private static String agentServer = null;
+    private static String agentInstallDir = null;
+
+    public static boolean register(String agentIp, Integer agentPort, String agentServer, String agentInstallDir) {
+        boolean registerSuccess = registerToServer(agentIp, agentPort, agentServer, agentInstallDir);
+        if (!registerSuccess) {
+            return false;
+        }
+
+        AgentContext.agentIp = agentIp;
+        AgentContext.agentPort = agentPort;
+        AgentContext.agentServer = agentServer;
+        AgentContext.agentInstallDir = agentInstallDir;
+
+        return true;
+    }
+
+    private static boolean registerToServer(String agentIp, Integer agentPort, String agentServer, String agentInstallDir) {
+        String requestUrl = "http://" + agentServer + "/api/server/register";
+        Map<String, Object> map = new HashMap<>();
+        map.put("host", agentIp);
+        map.put("port", agentPort);
+        map.put("installDir", agentInstallDir);
+
+        RResult res = null;
+        try {
+            String result = Request.sendPostRequest(requestUrl, map);
+            res = JSON.parseObject(result, RResult.class);
+        } catch (Exception ex) {
+            return false;
+        }
+        if (res != null && new Boolean(true).equals(res.getData())) {
+            return true;
+        }
+        return false;
+    }
+
+    public static String getAgentIp() {
+        return agentIp;
+    }
+
+    public static Integer getAgentPort() {
+        return agentPort;
+    }
+
+    public static String getAgentServer() {
+        return agentServer;
+    }
+
+    public static String getAgentInstallDir() {
+        return agentInstallDir;
+    }
+
+    public static Map<String, Object> getContext() {
+        HashMap<String, Object> context = new HashMap<>();
+        context.put("agentIp", AgentContext.agentIp);
+        context.put("agentPort", AgentContext.agentPort);
+        context.put("agentServer", AgentContext.agentServer);
+        context.put("agentInstallDir", AgentContext.agentInstallDir);
+        return context;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/AgentHeartbeat.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/AgentHeartbeat.java
new file mode 100644
index 0000000..880adce
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/AgentHeartbeat.java
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.register;
+
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.manager.agent.util.Request;
+import org.apache.doris.manager.common.domain.RResult;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class AgentHeartbeat {
+
+    private static final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
+
+    private static final long HEARTBEAT_TIME = 10000L;
+
+    public static void start() {
+        SCHEDULER.scheduleWithFixedDelay(() -> {
+            if (!heartbeat()) {
+                log.error("agent heartbeat fail!");
+            } else {
+                log.info("send heartbeat");
+            }
+        }, 0, HEARTBEAT_TIME, TimeUnit.MILLISECONDS);
+    }
+
+    private static boolean heartbeat() {
+        String requestUrl = "http://" + AgentContext.getAgentServer() + "/api/server/heartbeat";
+        Map<String, Object> map = new HashMap<>();
+        map.put("host", AgentContext.getAgentIp());
+        map.put("port", AgentContext.getAgentPort());
+
+        RResult res = null;
+        try {
+            String result = Request.sendPostRequest(requestUrl, map);
+            res = JSON.parseObject(result, RResult.class);
+        } catch (Exception ex) {
+            return false;
+        }
+        if (res != null && res.getCode() == 0) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/ApplicationOption.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/ApplicationOption.java
new file mode 100644
index 0000000..f57183b
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/register/ApplicationOption.java
@@ -0,0 +1,28 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.register;
+
+import org.kohsuke.args4j.Option;
+
+public class ApplicationOption {
+    @Option(name = "--agentIp", required = true, usage = "Specify agent agentIp")
+    public String agentIp;
+
+    @Option(name = "--agentServer", required = true, usage = "Specify agent agentServer agentServerIp:port")
+    public String agentServer;
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/BeService.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/BeService.java
new file mode 100644
index 0000000..b4efa43
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/BeService.java
@@ -0,0 +1,146 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class BeService extends Service {
+
+    private static final Logger TASKLOG = LoggerFactory.getLogger(AgentConstants.LOG_TYPE_TASK);
+
+    public BeService(String installDir) {
+        super(ServiceRole.BE, installDir, installDir + AgentConstants.BE_CONFIG_FILE_RELATIVE_PATH);
+        doLoad();
+    }
+
+    private static List<String> parseStorageDirs(String storageRootPath) {
+        ArrayList<String> list = new ArrayList<>();
+        String[] splitArr = storageRootPath.split(";");
+        for (String split : splitArr) {
+            if (split.trim().length() <= 0) {
+                continue;
+            }
+
+            int lastIndex = split.indexOf(",");
+            if (lastIndex == -1) {
+                list.add(split);
+            } else {
+                list.add(split.substring(0, lastIndex));
+            }
+        }
+        return list;
+    }
+
+    @Override
+    public void doLoad() {
+        String httpPortStr = getConfig().getProperty(AgentConstants.BE_CONFIG_KEY_HTTP_PORT);
+        if (Objects.isNull(httpPortStr)) {
+            throw new AgentException("get config failed, key:" + AgentConstants.BE_CONFIG_KEY_HTTP_PORT + ", configFile:" + getConfigFilePath());
+        }
+        httpPort = Integer.valueOf(httpPortStr);
+    }
+
+    @Override
+    public boolean isHealth() {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+
+        String requestUrl = "http://" + AgentContext.getAgentIp() + ":" + httpPort + "/api/health";
+
+        HttpGet httpget = new HttpGet(requestUrl);
+
+        RequestConfig requestConfig = RequestConfig.custom()
+                .setConnectTimeout(5000)
+                .setConnectionRequestTimeout(5000)
+                .setSocketTimeout(5000).build();
+        httpget.setConfig(requestConfig);
+
+        CloseableHttpResponse response = null;
+        String result = "";
+
+        try {
+            response = httpclient.execute(httpget);
+            result = EntityUtils.toString(response.getEntity());
+        } catch (IOException e) {
+            e.printStackTrace();
+            return false;
+        }
+
+        JSONObject jsonObject = JSON.parseObject(result);
+        if (jsonObject == null) {
+            return false;
+        }
+
+        String status = jsonObject.getString("status");
+        if ("ok".equalsIgnoreCase(status)) {
+            return true;
+        }
+        return false;
+    }
+
+    public void createStrorageDir() {
+        String storageVal = null;
+        String storageValInConfig = getConfig().getProperty(AgentConstants.BE_CONFIG_KEY_STORAGE_DIR);
+        if (Objects.nonNull(storageValInConfig) && storageValInConfig.contains("${DORIS_HOME}/")) {
+            String subDir = storageValInConfig.substring(storageValInConfig.indexOf("}/") + 1);
+            if (subDir.length() <= 1 || subDir.contains("${") || subDir.contains(".") || subDir.contains(";")) {
+                return;
+            }
+            storageVal = installDir + subDir;
+        } else if (Objects.nonNull(storageValInConfig) && storageValInConfig.startsWith("/")) {
+            storageVal = storageValInConfig;
+        } else {
+            TASKLOG.info("be storage path must be start ${DORIS_HOME} or /,path={}", storageVal);
+            throw new AgentException("parse be storage path failed");
+        }
+
+        if (Objects.nonNull(storageVal)) {
+            List<String> list = parseStorageDirs(storageVal);
+            for (String dir : list) {
+                File file = new File(dir);
+                if (!file.exists()) {
+                    boolean r = file.mkdirs();
+                    TASKLOG.info("create storage path:{},ret:{}", dir, r);
+                }
+            }
+        }
+    }
+
+    @Override
+    public String serviceProcessKeyword() {
+        return AgentConstants.PROCESS_KEYWORD_BE;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/BrokerService.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/BrokerService.java
new file mode 100644
index 0000000..cf1b356
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/BrokerService.java
@@ -0,0 +1,70 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.service;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Objects;
+
+@Slf4j
+public class BrokerService extends Service {
+    private Integer ipcPort;
+
+    public BrokerService(String installDir) {
+        super(ServiceRole.BROKER, installDir, installDir + AgentConstants.BROKER_CONFIG_FILE_RELATIVE_PATH);
+        doLoad();
+    }
+
+    @Override
+    public void doLoad() {
+        String port = getConfig().getProperty(AgentConstants.BROKER_CONFIG_KEY_IPC_PORT);
+        if (Objects.isNull(port)) {
+            throw new AgentException("get config failed, key:" + AgentConstants.BROKER_CONFIG_KEY_IPC_PORT + ", configFile:" + getConfigFilePath());
+        }
+        ipcPort = Integer.valueOf(port);
+    }
+
+    @Override
+    public boolean isHealth() {
+        Socket socket = new Socket();
+        try {
+            socket.connect(new InetSocketAddress("localhost", ipcPort));
+        } catch (IOException e) {
+            e.printStackTrace();
+            return false;
+        } finally {
+            try {
+                socket.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String serviceProcessKeyword() {
+        return AgentConstants.PROCESS_KEYWORD_BROKER;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/FeService.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/FeService.java
new file mode 100644
index 0000000..0a03f5a
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/FeService.java
@@ -0,0 +1,123 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.common.domain.ServiceRole;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Objects;
+
+@Slf4j
+public class FeService extends Service {
+
+    public FeService(String installDir) {
+        super(ServiceRole.FE, installDir, installDir + AgentConstants.FE_CONFIG_FILE_RELATIVE_PATH);
+        doLoad();
+    }
+
+    @Override
+    public void doLoad() {
+        String httpPortStr = getConfig().getProperty(AgentConstants.FE_CONFIG_KEY_HTTP_PORT);
+        if (Objects.isNull(httpPortStr)) {
+            throw new AgentException("get config failed, key:" + AgentConstants.FE_CONFIG_KEY_HTTP_PORT + ", configFile:" + getConfigFilePath());
+        }
+        httpPort = Integer.valueOf(httpPortStr);
+    }
+
+    @Override
+    public boolean isHealth() {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+
+        String requestUrl = "http://" + AgentContext.getAgentIp() + ":" + httpPort + "/api/bootstrap";
+
+        HttpGet httpget = new HttpGet(requestUrl);
+
+        RequestConfig requestConfig = RequestConfig.custom()
+                .setConnectTimeout(5000)
+                .setConnectionRequestTimeout(5000)
+                .setSocketTimeout(5000).build();
+        httpget.setConfig(requestConfig);
+
+        CloseableHttpResponse response = null;
+        String result = "";
+
+        try {
+            response = httpclient.execute(httpget);
+            result = EntityUtils.toString(response.getEntity());
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return false;
+        }
+
+        JSONObject jsonObject = JSON.parseObject(result);
+        if (jsonObject == null) {
+            return false;
+        }
+
+        String code = jsonObject.getString("code");
+        String msg = jsonObject.getString("msg");
+        String status = jsonObject.getString("status");
+        if (("0".equals(code) && "success".equalsIgnoreCase(msg)) || "OK".equalsIgnoreCase(status)) {
+            return true;
+        }
+        return false;
+    }
+
+    public void createMetaDir() {
+        String dir = null;
+        String metaDir = getConfig().getProperty(AgentConstants.FE_CONFIG_KEY_META_DIR);
+        if (Objects.nonNull(metaDir) && metaDir.contains("${DORIS_HOME}/")) {
+            String subDir = metaDir.substring(metaDir.indexOf("}/") + 1);
+            if (subDir.length() <= 1) {
+                return;
+            }
+            dir = installDir + subDir;
+        } else if (Objects.nonNull(metaDir) && metaDir.startsWith("/")) {
+            dir = metaDir;
+        } else {
+            dir = installDir + File.separator + metaDir;
+        }
+
+        if (Objects.nonNull(dir)) {
+            File file = new File(dir);
+            if (!file.exists()) {
+                boolean r = file.mkdirs();
+                log.info("create meta path:{},ret:{}", dir, r);
+            }
+        }
+    }
+
+    @Override
+    public String serviceProcessKeyword() {
+        return AgentConstants.PROCESS_KEYWORD_FE;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/Service.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/Service.java
new file mode 100644
index 0000000..e8e9e87
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/Service.java
@@ -0,0 +1,122 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.service;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+@Slf4j
+public abstract class Service {
+    protected ServiceRole serviceRole = null;
+    protected String installDir = null;
+    protected Integer httpPort = null;
+    protected String configFile = null;
+
+    public Service(ServiceRole serviceRole, String installDir, String configFilePath) {
+        this.serviceRole = serviceRole;
+        this.installDir = installDir;
+        this.configFile = configFilePath;
+        validService();
+    }
+
+    public void validService() {
+        File file = new File(this.installDir);
+        if (!file.exists() || !file.isDirectory()) {
+            throw new AgentException("service install dir not exists,dir:" + this.installDir);
+        }
+
+        File configFilePath = new File(this.configFile);
+        if (!configFilePath.exists() || !configFilePath.isFile()) {
+            throw new AgentException("service config file not exists,path:" + this.configFile);
+        }
+    }
+
+    public ServiceRole getServiceRole() {
+        return serviceRole;
+    }
+
+    public String getInstallDir() {
+        return installDir;
+    }
+
+    public Integer getHttpPort() {
+        return httpPort;
+    }
+
+    public abstract boolean isHealth();
+
+    public abstract String serviceProcessKeyword();
+
+    public boolean processExist() {
+        String comm = AgentConstants.BASH_BIN + AgentContext.getAgentInstallDir() + "/bin/process_exist.sh " + serviceProcessKeyword();
+        String[] commands = {"/bin/bash", "-c", comm};
+
+        int exitVal = AgentConstants.TASK_ERROR_CODE_DEFAULT;
+        try {
+            log.info("execute command:{}", StringUtils.join(commands, " "));
+            Process proc = Runtime.getRuntime().exec(commands);
+            exitVal = proc.waitFor();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        log.info("execute exit code:{}", exitVal);
+        return exitVal == AgentConstants.COMMAND_EXECUTE_SUCCESS_CODE;
+    }
+
+    public void load() {
+        doLoad();
+    }
+
+    public abstract void doLoad();
+
+    public Properties getConfig() {
+        String configPath = configFile;
+        Properties props;
+        try {
+            props = new Properties();
+            props.load(new FileReader(configPath));
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new AgentException("load conf file fail:" + configPath);
+        }
+        return props;
+    }
+
+    public String getConfigFilePath() {
+        return configFile;
+    }
+
+    @Override
+    public String toString() {
+        return "Service{"
+                + "serviceRole=" + serviceRole
+                + ", installDir='" + installDir + '\''
+                + '}';
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/ServiceContext.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/ServiceContext.java
new file mode 100644
index 0000000..6a8b444
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/service/ServiceContext.java
@@ -0,0 +1,114 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.service;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.doris.manager.agent.exception.AgentException;
+import org.apache.doris.manager.agent.register.AgentContext;
+import org.apache.doris.manager.agent.util.Request;
+import org.apache.doris.manager.common.domain.AgentRoleRegister;
+import org.apache.doris.manager.common.domain.RResult;
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+public class ServiceContext {
+    private static Map<ServiceRole, Service> serviceMap = new HashMap<>();
+
+    private static synchronized void registeService(Service service) {
+        serviceMap.put(service.getServiceRole(), service);
+    }
+
+    public static Map<ServiceRole, Service> getServiceMap() {
+        return new HashMap<>(serviceMap);
+    }
+
+    public static boolean register(Service service) {
+        boolean b = registerToServer(AgentContext.getAgentServer(), AgentContext.getAgentIp(), service.getServiceRole(), service.getInstallDir());
+        if (!b) {
+            throw new AgentException("register to server failed,server:" + AgentContext.getAgentServer()
+                    + ",agentIp:" + AgentContext.getAgentIp()
+                    + ",service:" + service.toString());
+        }
+        registeService(service);
+        return true;
+    }
+
+    public static boolean registerFromServer(String serverIpPort, String agentIp) {
+        List<AgentRoleRegister> list = queryServiceList(serverIpPort, agentIp);
+        if (Objects.isNull(list)) {
+            throw new AgentException("query service from server failed, server:" + serverIpPort + ",agentIp:" + agentIp);
+        }
+
+        if (list.isEmpty()) {
+            return true;
+        }
+
+        for (AgentRoleRegister service : list) {
+            if (ServiceRole.findByName(service.getRole()) == ServiceRole.FE) {
+                FeService feService = new FeService(service.getInstallDir());
+                registeService(feService);
+            } else if (ServiceRole.findByName(service.getRole()) == ServiceRole.BE) {
+                BeService beService = new BeService(service.getInstallDir());
+                registeService(beService);
+            } else if (ServiceRole.findByName(service.getRole()) == ServiceRole.BROKER) {
+                BrokerService brokerService = new BrokerService(service.getInstallDir());
+                registeService(brokerService);
+            }
+        }
+
+        return true;
+    }
+
+    private static boolean registerToServer(String serverIpPort, String agentIp, ServiceRole role, String serviceInstallDir) {
+        String requestUrl = "http://" + serverIpPort + "/api/agent/register";
+        Map<String, Object> map = new HashMap<>();
+        map.put("host", agentIp);
+        map.put("role", role.name());
+        map.put("installDir", serviceInstallDir);
+
+        RResult res = null;
+        try {
+            String result = Request.sendPostRequest(requestUrl, map);
+            res = JSON.parseObject(result, RResult.class);
+        } catch (Exception ex) {
+            return false;
+        }
+        if (res != null && new Boolean(true).equals(res.getData())) {
+            return true;
+        }
+        return false;
+    }
+
+    private static List<AgentRoleRegister> queryServiceList(String serverIpPort, String agentIp) {
+        String requestUrl = "http://" + serverIpPort + "/api/server/agentRole";
+        Map<String, Object> map = new HashMap<>();
+        map.put("host", agentIp);
+
+        String result = Request.sendGetRequest(requestUrl, map);
+        RResult resultResp = JSON.parseObject(result, RResult.class);
+        if (resultResp == null || resultResp.getCode() != 0) {
+            return null;
+        }
+        List<AgentRoleRegister> agentRoles = JSON.parseArray(JSON.toJSONString(resultResp.getData()), AgentRoleRegister.class);
+        return agentRoles;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/AbsAsyncTaskHandler.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/AbsAsyncTaskHandler.java
new file mode 100644
index 0000000..95ed2e6
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/AbsAsyncTaskHandler.java
@@ -0,0 +1,41 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import org.apache.doris.manager.common.domain.TaskState;
+
+import java.util.concurrent.ExecutorService;
+
+public abstract class AbsAsyncTaskHandler extends TaskHandler {
+
+    @Override
+    public void doHandle(Task task) {
+        task.getTaskResult().setTaskState(TaskState.QUEUED);
+
+        TaskContext.register(task);
+        getExecutorService().submit(new Runnable() {
+            @Override
+            public void run() {
+                task.executeTask();
+            }
+        });
+    }
+
+    public abstract ExecutorService getExecutorService();
+
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ITaskHandlerFactory.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ITaskHandlerFactory.java
new file mode 100644
index 0000000..5f77a00
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ITaskHandlerFactory.java
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+public interface ITaskHandlerFactory {
+    TaskHandler createTaskHandler();
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/LRU.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/LRU.java
new file mode 100644
index 0000000..2ee44f0
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/LRU.java
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class LRU<K, V> {
+    private final float loadFactory = 0.75f;
+    private LinkedHashMap<K, V> map;
+
+    public LRU(int maxCacheSize) {
+        int capacity = (int) Math.ceil(maxCacheSize / this.loadFactory) + 1;
+        map = new LinkedHashMap<K, V>(capacity, loadFactory, false) {
+            @Override
+            protected boolean removeEldestEntry(Map.Entry eldest) {
+                return size() > maxCacheSize;
+            }
+        };
+    }
+
+    public void put(K key, V value) {
+        map.put(key, value);
+    }
+
+    public V get(K key) {
+        return map.get(key);
+    }
+
+    public void remove(K key) {
+        map.remove(key);
+    }
+
+    public boolean contain(K key) {
+        return map.containsKey(key);
+    }
+
+    public int size() {
+        return map.size();
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/QueuedTaskHandler.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/QueuedTaskHandler.java
new file mode 100644
index 0000000..8452f8a
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/QueuedTaskHandler.java
@@ -0,0 +1,27 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import java.util.concurrent.ExecutorService;
+
+public class QueuedTaskHandler extends AbsAsyncTaskHandler {
+    @Override
+    public ExecutorService getExecutorService() {
+        return TaskExecutorService.getSingleThreadExecutor();
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/QueuedTaskHandlerFactory.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/QueuedTaskHandlerFactory.java
new file mode 100644
index 0000000..5ed2283
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/QueuedTaskHandlerFactory.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+public class QueuedTaskHandlerFactory implements ITaskHandlerFactory {
+    private static TaskHandler instance = null;
+
+    @Override
+    public TaskHandler createTaskHandler() {
+        if (instance == null) {
+            synchronized (QueuedTaskHandlerFactory.class) {
+                if (instance == null) {
+                    instance = new QueuedTaskHandler();
+                }
+            }
+        }
+        return instance;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ScriptTask.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ScriptTask.java
new file mode 100644
index 0000000..815bbed
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ScriptTask.java
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class ScriptTask extends Task<ScriptTaskDesc> {
+
+    private static final Logger TASKLOG = LoggerFactory.getLogger(AgentConstants.LOG_TYPE_TASK);
+
+    public ScriptTask(ScriptTaskDesc taskDesc) {
+        super(taskDesc);
+    }
+
+    public ScriptTask(ScriptTaskDesc taskDesc, TaskHook taskHook) {
+        super(taskDesc, taskHook);
+    }
+
+    @Override
+    protected int execute() throws IOException, InterruptedException {
+        Runtime rt = Runtime.getRuntime();
+        String[] commands = {"/bin/bash", "-c", ""};
+        commands[2] = taskDesc.getScriptCmd();
+        Process proc = rt.exec(commands);
+        BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+        BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
+
+        TASKLOG.info("scriptCmd:{}", taskDesc.getScriptCmd());
+
+        String s = null;
+        while ((s = stdInput.readLine()) != null) {
+            TASKLOG.info(s);
+        }
+
+        while ((s = stdError.readLine()) != null) {
+            TASKLOG.info(s);
+        }
+
+        int exitVal = proc.waitFor();
+        return exitVal;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ScriptTaskDesc.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ScriptTaskDesc.java
new file mode 100644
index 0000000..261ddd1
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/ScriptTaskDesc.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+public class ScriptTaskDesc extends TaskDesc {
+    private String scriptCmd;
+
+    public String getScriptCmd() {
+        return scriptCmd;
+    }
+
+    public void setScriptCmd(String scriptCmd) {
+        this.scriptCmd = scriptCmd;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/SyncTaskHandler.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/SyncTaskHandler.java
new file mode 100644
index 0000000..4a51e61
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/SyncTaskHandler.java
@@ -0,0 +1,26 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+public class SyncTaskHandler extends TaskHandler {
+
+    @Override
+    public void doHandle(Task task) {
+        task.executeTask();
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/SyncTaskHandlerFactory.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/SyncTaskHandlerFactory.java
new file mode 100644
index 0000000..984f208
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/SyncTaskHandlerFactory.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+public class SyncTaskHandlerFactory implements ITaskHandlerFactory {
+    private static TaskHandler instance = null;
+
+    @Override
+    public TaskHandler createTaskHandler() {
+        if (instance == null) {
+            synchronized (SyncTaskHandlerFactory.class) {
+                if (instance == null) {
+                    instance = new SyncTaskHandler();
+                }
+            }
+        }
+        return instance;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/Task.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/Task.java
new file mode 100644
index 0000000..78788a8
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/Task.java
@@ -0,0 +1,85 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+import org.apache.doris.manager.common.domain.TaskResult;
+import org.apache.doris.manager.common.domain.TaskState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.UUID;
+
+public abstract class Task<T extends TaskDesc> {
+    private static final Logger TASKLOG = LoggerFactory.getLogger(AgentConstants.LOG_TYPE_TASK);
+
+    protected T taskDesc;
+
+    private TaskResult taskResult;
+
+    private TaskHook taskHook;
+
+    protected Task(T taskDesc) {
+        this.taskDesc = taskDesc;
+        this.taskResult = new TaskResult();
+        this.taskResult.setTaskId(UUID.randomUUID().toString().replace("-", ""));
+    }
+
+    public Task(T taskDesc, TaskHook taskHook) {
+        this(taskDesc);
+        this.taskHook = taskHook;
+    }
+
+    public String getTaskId() {
+        return this.taskResult.getTaskId();
+    }
+
+    public TaskResult getTaskResult() {
+        return taskResult;
+    }
+
+    public TaskResult executeTask() {
+        this.taskResult.setStartTime(new Date());
+        this.taskResult.setTaskState(TaskState.RUNNING);
+        int code = AgentConstants.TASK_ERROR_CODE_DEFAULT;
+        try {
+            code = execute();
+            if (0 == code && taskHook != null) {
+                taskHook.onSuccess(taskDesc);
+            }
+        } catch (Throwable e) {
+            code = AgentConstants.TASK_ERROR_CODE_EXCEPTION;
+            e.printStackTrace();
+            TASKLOG.info(e.getMessage());
+        } finally {
+            this.taskResult.setEndTime(new Date());
+            this.taskResult.setRetCode(code);
+            this.taskResult.setTaskState(TaskState.FINISHED);
+        }
+        return this.taskResult;
+    }
+
+    public T getTaskDesc() {
+        return taskDesc;
+    }
+
+    protected abstract int execute() throws IOException, InterruptedException;
+
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskContext.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskContext.java
new file mode 100644
index 0000000..b757d2d
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskContext.java
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import org.apache.doris.manager.agent.common.AgentConstants;
+
+public class TaskContext {
+    private static final LRU<String, Task> TASK_LRU = new LRU<>(AgentConstants.COMMAND_HISTORY_SAVE_MAX_COUNT);
+
+    public static synchronized void register(Task task) {
+        TASK_LRU.put(task.getTaskId(), task);
+    }
+
+    public static synchronized void unregister(Task task) {
+        TASK_LRU.remove(task.getTaskId());
+    }
+
+    public static synchronized Task getTaskByTaskId(String taskId) {
+        return TASK_LRU.get(taskId);
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskDesc.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskDesc.java
new file mode 100644
index 0000000..1bbb728
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskDesc.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+public class TaskDesc {
+    private String taskName;
+
+    public String getTaskName() {
+        return taskName;
+    }
+
+    public void setTaskName(String taskName) {
+        this.taskName = taskName;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskExecutorService.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskExecutorService.java
new file mode 100644
index 0000000..0f27c16
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskExecutorService.java
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class TaskExecutorService {
+    private static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
+
+    public static ExecutorService getSingleThreadExecutor() {
+        return singleThreadExecutor;
+    }
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHandler.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHandler.java
new file mode 100644
index 0000000..52e26a1
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHandler.java
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import java.util.Date;
+
+public abstract class TaskHandler {
+    public void handle(Task task) {
+        task.getTaskResult().setSubmitTime(new Date());
+        doHandle(task);
+    }
+
+    public abstract void doHandle(Task task);
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHandlerFactory.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHandlerFactory.java
new file mode 100644
index 0000000..2dfd564
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHandlerFactory.java
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+import org.apache.doris.manager.agent.exception.AgentException;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public final class TaskHandlerFactory {
+    private static Map<Class, ITaskHandlerFactory> factoryInstanceMap = new ConcurrentHashMap<>();
+
+    public static ITaskHandlerFactory getTaskHandlerFactory(Class<? extends ITaskHandlerFactory> className) {
+        synchronized (factoryInstanceMap) {
+            if (!factoryInstanceMap.containsKey(className)) {
+                ITaskHandlerFactory factory = null;
+                try {
+                    Class<? extends ITaskHandlerFactory> factoryClass = (Class<? extends ITaskHandlerFactory>) Class.forName(className.getName());
+                    factory = factoryClass.newInstance();
+                    factoryInstanceMap.put(className, factory);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw new AgentException("failed create factory:" + className.getName());
+                }
+                return factory;
+            }
+            return factoryInstanceMap.get(className);
+        }
+    }
+
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHook.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHook.java
new file mode 100644
index 0000000..1fa882b
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/task/TaskHook.java
@@ -0,0 +1,22 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.task;
+
+public abstract class TaskHook<T extends TaskDesc> {
+    public abstract void onSuccess(T taskDesc);
+}
diff --git a/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/util/Request.java b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/util/Request.java
new file mode 100644
index 0000000..a71321f
--- /dev/null
+++ b/manager/dm-agent/src/main/java/org/apache/doris/manager/agent/util/Request.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.agent.util;
+
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+public class Request {
+
+    public static String sendPostRequest(String requestUrl, Map<String, Object> params) {
+        HttpPost httpPost = new HttpPost(requestUrl);
+        httpPost.setConfig(timeout());
+
+        httpPost.setEntity(new StringEntity(JSON.toJSONString(params), "utf-8"));
+        httpPost.addHeader("Content-Type", "application/json");
+
+        try {
+            return request(httpPost);
+        } catch (IOException e) {
+            log.error("request url error:{},param:{}", requestUrl, params, e);
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String sendGetRequest(String requestUrl, Map<String, Object> params) {
+        URI url = null;
+        try {
+            URIBuilder uriBuilder = null;
+            uriBuilder = new URIBuilder(requestUrl);
+            for (Map.Entry<String, Object> param : params.entrySet()) {
+                uriBuilder.addParameter(param.getKey(), String.valueOf(param.getValue()));
+            }
+            url = uriBuilder.build();
+        } catch (URISyntaxException e) {
+            e.printStackTrace();
+        }
+
+        HttpGet httpGet = new HttpGet(url);
+        httpGet.setConfig(timeout());
+
+        try {
+            return request(httpGet);
+        } catch (IOException e) {
+            log.error("request url error:{},param:{}", requestUrl, params, e);
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static String request(HttpUriRequest request) throws IOException {
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        CloseableHttpResponse response = httpclient.execute(request);
+        String result = EntityUtils.toString(response.getEntity());
+        close(response, httpclient);
+        return result;
+    }
+
+    public static void close(CloseableHttpResponse response, CloseableHttpClient httpClient) {
+        try {
+            if (response != null) {
+                response.close();
+            }
+            if (httpClient != null) {
+                httpClient.close();
+            }
+        } catch (IOException e) {
+            log.error("close http connection failed", e);
+        }
+    }
+
+    public static RequestConfig timeout() {
+        RequestConfig requestConfig = RequestConfig.custom()
+                .setConnectTimeout(5000)
+                .setConnectionRequestTimeout(5000)
+                .setSocketTimeout(5000).build();
+        return requestConfig;
+    }
+
+    public static void main(String[] args) {
+        String rResult = sendGetRequest("http://www.baidu.com", new HashMap<>());
+        System.out.println(rResult);
+
+    }
+}
diff --git a/manager/dm-agent/src/main/resources/application.properties b/manager/dm-agent/src/main/resources/application.properties
new file mode 100644
index 0000000..ee817a8
--- /dev/null
+++ b/manager/dm-agent/src/main/resources/application.properties
@@ -0,0 +1 @@
+server.port=9602
diff --git a/manager/dm-agent/src/main/resources/logback-spring.xml b/manager/dm-agent/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..0bac9d4
--- /dev/null
+++ b/manager/dm-agent/src/main/resources/logback-spring.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<configuration debug="false">
+    <springProperty scope="context" name="springAppName" source="spring.application.name" defaultValue="agent"/>
+    <property name="LOG_HOME" value="./log"/>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <FileNamePattern>${LOG_HOME}/${springAppName}.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <maxFileSize>50MB</maxFileSize>
+            <totalSizeCap>10GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="TASK_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/task.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <FileNamePattern>${LOG_HOME}/task.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <maxFileSize>50MB</maxFileSize>
+            <totalSizeCap>10GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT"/>
+        <appender-ref ref="FILE"/>
+    </root>
+
+    <logger name="TASK_LOG" additivity="false" level="INFO">
+        <appender-ref ref="TASK_LOG_FILE"/>
+    </logger>
+</configuration>
\ No newline at end of file
diff --git a/manager/dm-common/pom.xml b/manager/dm-common/pom.xml
new file mode 100644
index 0000000..a7c8c75
--- /dev/null
+++ b/manager/dm-common/pom.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>doris-manager</artifactId>
+        <groupId>org.apache.doris</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dm-common</artifactId>
+    <!--    <packaging>jar</packaging>-->
+
+</project>
\ No newline at end of file
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/AgentRoleRegister.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/AgentRoleRegister.java
new file mode 100644
index 0000000..764cfe6
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/AgentRoleRegister.java
@@ -0,0 +1,62 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+/**
+ * agent role resgiter entity
+ **/
+public class AgentRoleRegister {
+    private String host;
+
+    private String role;
+
+    private String installDir;
+
+    public AgentRoleRegister() {
+    }
+
+    public AgentRoleRegister(String host, String role, String installDir) {
+        this.host = host;
+        this.role = role;
+        this.installDir = installDir;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public String getRole() {
+        return role;
+    }
+
+    public void setRole(String role) {
+        this.role = role;
+    }
+
+    public String getInstallDir() {
+        return installDir;
+    }
+
+    public void setInstallDir(String installDir) {
+        this.installDir = installDir;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BeInstallCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BeInstallCommandRequestBody.java
new file mode 100644
index 0000000..2843c51
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BeInstallCommandRequestBody.java
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class BeInstallCommandRequestBody {
+    private String installDir;
+
+    private String packageUrl;
+
+    private boolean mkBeStorageDir = false;
+
+    public boolean isMkBeStorageDir() {
+        return mkBeStorageDir;
+    }
+
+    public void setMkBeStorageDir(boolean mkBeStorageDir) {
+        this.mkBeStorageDir = mkBeStorageDir;
+    }
+
+    public String getPackageUrl() {
+        return packageUrl;
+    }
+
+    public void setPackageUrl(String packageUrl) {
+        this.packageUrl = packageUrl;
+    }
+
+    public String getInstallDir() {
+        return installDir;
+    }
+
+    public void setInstallDir(String installDir) {
+        this.installDir = installDir;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BeStartCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BeStartCommandRequestBody.java
new file mode 100644
index 0000000..aa9b763
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BeStartCommandRequestBody.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class BeStartCommandRequestBody {
+    private boolean stopBeforeStart;
+
+    public boolean isStopBeforeStart() {
+        return stopBeforeStart;
+    }
+
+    public void setStopBeforeStart(boolean stopBeforeStart) {
+        this.stopBeforeStart = stopBeforeStart;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BrokerInstallCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BrokerInstallCommandRequestBody.java
new file mode 100644
index 0000000..4de8ae3
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BrokerInstallCommandRequestBody.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class BrokerInstallCommandRequestBody {
+    private String installDir;
+
+    private String packageUrl;
+
+    public String getPackageUrl() {
+        return packageUrl;
+    }
+
+    public void setPackageUrl(String packageUrl) {
+        this.packageUrl = packageUrl;
+    }
+
+    public String getInstallDir() {
+        return installDir;
+    }
+
+    public void setInstallDir(String installDir) {
+        this.installDir = installDir;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BrokerStartCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BrokerStartCommandRequestBody.java
new file mode 100644
index 0000000..50cb444
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/BrokerStartCommandRequestBody.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class BrokerStartCommandRequestBody {
+    private boolean stopBeforeStart;
+
+    public boolean isStopBeforeStart() {
+        return stopBeforeStart;
+    }
+
+    public void setStopBeforeStart(boolean stopBeforeStart) {
+        this.stopBeforeStart = stopBeforeStart;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandRequest.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandRequest.java
new file mode 100644
index 0000000..78a652e
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandRequest.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class CommandRequest {
+    private String commandType;
+
+    private String body;
+
+    public String getCommandType() {
+        return commandType;
+    }
+
+    public void setCommandType(String commandType) {
+        this.commandType = commandType;
+    }
+
+    public String getBody() {
+        return body;
+    }
+
+    public void setBody(String body) {
+        this.body = body;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandResult.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandResult.java
new file mode 100644
index 0000000..5503dad
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandResult.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class CommandResult {
+    private TaskResult taskResult;
+
+    public CommandResult(TaskResult taskResult) {
+        this.taskResult = taskResult;
+    }
+
+    public TaskResult getTaskResult() {
+        return taskResult;
+    }
+
+    public void setTaskResult(TaskResult taskResult) {
+        this.taskResult = taskResult;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandType.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandType.java
new file mode 100644
index 0000000..03c7218
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/CommandType.java
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public enum CommandType {
+    INSTALL_FE,
+
+    INSTALL_BE,
+
+    START_FE,
+
+    STOP_FE,
+
+    START_BE,
+
+    STOP_BE,
+
+    WRITE_FE_CONF,
+
+    WRITE_BE_CONF,
+
+    INSTALL_BROKER,
+
+    START_BROKER,
+
+    STOP_BROKER,
+
+    WRITE_BROKER_CONF;
+
+    public static CommandType findByName(String name) {
+        for (CommandType type : CommandType.values()) {
+            if (type.name().equals(name)) {
+                return type;
+            }
+        }
+        return null;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/FeInstallCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/FeInstallCommandRequestBody.java
new file mode 100644
index 0000000..fbad2a3
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/FeInstallCommandRequestBody.java
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class FeInstallCommandRequestBody {
+    private String packageUrl;
+    private String installDir;
+    private Boolean mkFeMetadir = false;
+
+    public String getInstallDir() {
+        return installDir;
+    }
+
+    public void setInstallDir(String installDir) {
+        this.installDir = installDir;
+    }
+
+    public String getPackageUrl() {
+        return packageUrl;
+    }
+
+    public void setPackageUrl(String packageUrl) {
+        this.packageUrl = packageUrl;
+    }
+
+    public Boolean getMkFeMetadir() {
+        return mkFeMetadir;
+    }
+
+    public void setMkFeMetadir(Boolean mkFeMetadir) {
+        this.mkFeMetadir = mkFeMetadir;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/FeStartCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/FeStartCommandRequestBody.java
new file mode 100644
index 0000000..2e6a7c8
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/FeStartCommandRequestBody.java
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class FeStartCommandRequestBody {
+    private String helpHostPort;
+    private boolean stopBeforeStart;
+
+    public String getHelpHostPort() {
+        return helpHostPort;
+    }
+
+    public void setHelpHostPort(String helpHostPort) {
+        this.helpHostPort = helpHostPort;
+    }
+
+    public boolean isStopBeforeStart() {
+        return stopBeforeStart;
+    }
+
+    public void setStopBeforeStart(boolean stopBeforeStart) {
+        this.stopBeforeStart = stopBeforeStart;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/HardwareInfo.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/HardwareInfo.java
new file mode 100644
index 0000000..eeca9e9
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/HardwareInfo.java
@@ -0,0 +1,54 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+/**
+ * hardware info
+ **/
+public class HardwareInfo {
+
+    private String host;
+
+    private String cpu;
+
+    private String totalMemory;
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public String getCpu() {
+        return cpu;
+    }
+
+    public void setCpu(String cpu) {
+        this.cpu = cpu;
+    }
+
+    public String getTotalMemory() {
+        return totalMemory;
+    }
+
+    public void setTotalMemory(String totalMemory) {
+        this.totalMemory = totalMemory;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/RResult.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/RResult.java
new file mode 100644
index 0000000..02bc07c
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/RResult.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+import java.util.HashMap;
+import java.util.Objects;
+
+public class RResult extends HashMap<String, Object> {
+    public static final String CODE_TAG = "code";
+    public static final String MSG_TAG = "msg";
+    public static final String DATA_TAG = "data";
+    private static final long serialVersionUID = 1L;
+    private static final int CODE_SUCCESS = 0;
+    private static final int CODE_FAILED = 500;
+
+    public RResult() {
+    }
+
+    public RResult(int code, String msg) {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+    }
+
+    public RResult(int code, String msg, Object data) {
+        super.put(CODE_TAG, code);
+        super.put(MSG_TAG, msg);
+        if (!Objects.isNull(data)) {
+            super.put(DATA_TAG, data);
+        }
+    }
+
+    public static RResult success() {
+        return RResult.success("success");
+    }
+
+    public static RResult success(Object data) {
+        return RResult.success("success", data);
+    }
+
+    public static RResult success(String msg) {
+        return RResult.success(msg, null);
+    }
+
+    public static RResult success(String msg, Object data) {
+        return new RResult(CODE_SUCCESS, msg, data);
+    }
+
+    public static RResult error() {
+        return RResult.error("fail");
+    }
+
+    public static RResult error(String msg) {
+        return RResult.error(msg, null);
+    }
+
+    public static RResult error(String msg, Object data) {
+        return new RResult(CODE_FAILED, msg, data);
+    }
+
+    public static RResult error(int code, String msg) {
+        return new RResult(code, msg, null);
+    }
+
+    public Object getData() {
+        return this.get("data");
+    }
+
+    public int getCode() {
+        return (int) this.get("code");
+    }
+
+    public boolean isSuccess() {
+        return getCode() == CODE_SUCCESS;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/ServiceRole.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/ServiceRole.java
new file mode 100644
index 0000000..8caef0d
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/ServiceRole.java
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public enum ServiceRole {
+    FE("fe"),
+    BE("be"),
+    BROKER("apache_hdfs_broker");
+
+    private String installName;
+
+    ServiceRole(String installName) {
+        this.installName = installName;
+    }
+
+    public static ServiceRole findByName(String name) {
+        for (ServiceRole type : ServiceRole.values()) {
+            if (type.name().equals(name)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    public String getInstallName() {
+        return installName;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/TaskResult.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/TaskResult.java
new file mode 100644
index 0000000..52b9e50
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/TaskResult.java
@@ -0,0 +1,89 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+import java.util.Date;
+
+public class TaskResult {
+    private String taskId;
+    private Date submitTime;
+    private Date startTime;
+    private Date endTime;
+    private TaskState taskState;
+    private Integer retCode;
+
+    public TaskResult() {
+    }
+
+    public TaskResult(TaskResult taskResult) {
+        this.taskId = taskResult.getTaskId();
+        this.submitTime = taskResult.getSubmitTime();
+        this.startTime = taskResult.getStartTime();
+        this.endTime = taskResult.getEndTime();
+        this.taskState = taskResult.getTaskState();
+        this.retCode = taskResult.getRetCode();
+    }
+
+    public TaskState getTaskState() {
+        return taskState;
+    }
+
+    public void setTaskState(TaskState taskState) {
+        this.taskState = taskState;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public String getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(String taskId) {
+        this.taskId = taskId;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+
+    public Integer getRetCode() {
+        return retCode;
+    }
+
+    public void setRetCode(Integer retCode) {
+        this.retCode = retCode;
+    }
+
+    public Date getSubmitTime() {
+        return submitTime;
+    }
+
+    public void setSubmitTime(Date submitTime) {
+        this.submitTime = submitTime;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/TaskState.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/TaskState.java
new file mode 100644
index 0000000..71769c4
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/TaskState.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public enum TaskState {
+    // Task has been queued for execution by the driver
+    INITIALIZED,
+    // Task has been queued for execution by the driver
+    QUEUED,
+    // Task is currently running
+    RUNNING,
+    // Task has completed
+    FINISHED,
+    // Task state is unkown
+    UNKNOWN;
+
+    public boolean typeIsRunning() {
+        return this == INITIALIZED || this == QUEUED || this == RUNNING;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteBeConfCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteBeConfCommandRequestBody.java
new file mode 100644
index 0000000..dc6c4c7
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteBeConfCommandRequestBody.java
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class WriteBeConfCommandRequestBody {
+    private String content;
+    private boolean createStorageDir;
+
+    public boolean isCreateStorageDir() {
+        return createStorageDir;
+    }
+
+    public void setCreateStorageDir(boolean createStorageDir) {
+        this.createStorageDir = createStorageDir;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteBrokerConfCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteBrokerConfCommandRequestBody.java
new file mode 100644
index 0000000..91353f5
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteBrokerConfCommandRequestBody.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class WriteBrokerConfCommandRequestBody {
+    private String content;
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+}
diff --git a/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteFeConfCommandRequestBody.java b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteFeConfCommandRequestBody.java
new file mode 100644
index 0000000..e67974f
--- /dev/null
+++ b/manager/dm-common/src/main/java/org/apache/doris/manager/common/domain/WriteFeConfCommandRequestBody.java
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.manager.common.domain;
+
+public class WriteFeConfCommandRequestBody {
+    private String content;
+    private boolean createMetaDir;
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public boolean isCreateMetaDir() {
+        return createMetaDir;
+    }
+
+    public void setCreateMetaDir(boolean createMetaDir) {
+        this.createMetaDir = createMetaDir;
+    }
+}
diff --git a/manager/dm-server/pom.xml b/manager/dm-server/pom.xml
new file mode 100644
index 0000000..51db1db
--- /dev/null
+++ b/manager/dm-server/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.doris</groupId>
+        <artifactId>doris-manager</artifactId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dm-server</artifactId>
+    <!--    <packaging>jar</packaging>-->
+
+    <name>dm-server</name>
+
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.doris</groupId>
+            <artifactId>dm-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.doris</groupId>
+            <artifactId>general</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.doris</groupId>
+            <artifactId>manager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentCache.java b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentCache.java
new file mode 100644
index 0000000..988eca8
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentCache.java
@@ -0,0 +1,104 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.agent;
+
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.stack.component.AgentComponent;
+import org.apache.doris.stack.entity.AgentEntity;
+import org.apache.doris.stack.exceptions.ServerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+/**
+ * agent host port cache
+ **/
+@Slf4j
+@Component
+public class AgentCache {
+
+    private static Map<String, AgentEntity> hostAgentCache = new ConcurrentHashMap<>();
+
+    @Autowired
+    private AgentComponent agentComponent;
+
+    @PostConstruct
+    public void init() {
+        loadAgents();
+    }
+
+    private void loadAgents() {
+        List<AgentEntity> agentEntities = agentComponent.queryAgentNodes(Lists.newArrayList());
+        if (agentEntities != null && !agentEntities.isEmpty()) {
+            Map<String, AgentEntity> agentsMap = agentEntities.stream().collect(Collectors.toMap(AgentEntity::getHost, v -> v, (v1, v2) -> v1));
+            hostAgentCache.putAll(agentsMap);
+        }
+    }
+
+    /**
+     * get agent from cache by host
+     */
+    public AgentEntity agentInfo(String host) {
+        return hostAgentCache.get(host);
+    }
+
+    /**
+     * get agent from cache by host
+     */
+    public Boolean containsAgent(String host) {
+        return hostAgentCache.containsKey(host);
+    }
+
+    /**
+     * put agent to cache
+     */
+    public void putAgent(AgentEntity agent) {
+        hostAgentCache.put(agent.getHost(), agent);
+    }
+
+    /**
+     * remove agent from cache
+     */
+    public void removeAgent(String host) {
+        hostAgentCache.remove(host);
+    }
+
+    /**
+     * query agent port by host
+     */
+    public int agentPort(String host) {
+        AgentEntity agent = agentInfo(host);
+        if (agent == null) {
+            log.error("failed query agent {} port", host);
+            throw new ServerException("query agent port fail");
+        }
+        return agent.getPort();
+    }
+
+    public void refresh(List<AgentEntity> agentEntities) {
+        hostAgentCache.clear();
+        Map<String, AgentEntity> agentsMap = agentEntities.stream().collect(Collectors.toMap(AgentEntity::getHost, v -> v, (v1, v2) -> v1));
+        hostAgentCache.putAll(agentsMap);
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentHeatbeatRunner.java b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentHeatbeatRunner.java
new file mode 100644
index 0000000..f934a33
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentHeatbeatRunner.java
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.agent;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.stack.constants.AgentStatus;
+import org.apache.doris.stack.dao.AgentRepository;
+import org.apache.doris.stack.entity.AgentEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * agent status check
+ **/
+@Component
+@Slf4j
+public class AgentHeatbeatRunner implements ApplicationRunner {
+
+    private static final long HEALTH_TIME = 60 * 1000L;
+    private static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+
+    @Autowired
+    private AgentRepository agentRepository;
+
+    @Autowired
+    private AgentCache agentCache;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        this.scheduler.scheduleWithFixedDelay(() -> {
+            try {
+                heartbeatCheck();
+            } catch (Exception ex) {
+                log.error("heartbeat check fail:", ex);
+                ex.printStackTrace();
+            }
+        }, HEALTH_TIME, HEALTH_TIME, TimeUnit.MILLISECONDS);
+    }
+
+    /**
+     * The last heartbeat time exceeds the HEALTH_TIME and is recognized as unhealthy
+     */
+    private void heartbeatCheck() {
+        long currTime = System.currentTimeMillis();
+        List<AgentEntity> agents = agentRepository.findAll();
+        for (AgentEntity agent : agents) {
+            Date lastReportedTime = agent.getLastReportedTime();
+            if (lastReportedTime == null) {
+                continue;
+            }
+            long diff = currTime - lastReportedTime.getTime();
+            if (diff > HEALTH_TIME) {
+                agent.setStatus(AgentStatus.STOP);
+                agentRepository.save(agent);
+                agentCache.putAgent(agent);
+                log.warn("agent {} is unhealthly", agent.getHost());
+            }
+        }
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentRest.java b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentRest.java
new file mode 100644
index 0000000..dc76c61
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentRest.java
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.agent;
+
+import com.alibaba.fastjson.JSON;
+import com.google.common.collect.Maps;
+import org.apache.doris.manager.common.domain.HardwareInfo;
+import org.apache.doris.manager.common.domain.RResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * agent rest api
+ **/
+@Component
+public class AgentRest {
+
+    private static final String AGENT_COMMAND_EXEC = "http://%s:%s/command/execute";
+    private static final String AGENT_TASK_INFO = "http://%s:%s/command/result?taskId={taskId}";
+    private static final String SERVICE_CONFIG = "http://%s:%s/service/config?serviceRole={serviceRole}";
+    private static final String SERVICE_LOG = "http://%s:%s/log?type={type}";
+    private static final String AGENT_TASK_LOG = "http://%s:%s/log/task?taskId={taskId}";
+    private static final String HARDWARE_INFO = "http://%s:%s/hardware/view";
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    public RResult commandExec(String host, Integer port, Object param) {
+        String restUrl = String.format(AGENT_COMMAND_EXEC, host, port);
+        RResult result = restTemplate.postForObject(restUrl, param, RResult.class);
+        return result;
+    }
+
+    public RResult serverLog(String host, Integer port, String type) {
+        Map<String, Object> param = Maps.newHashMap();
+        param.put("type", type);
+        String restUrl = String.format(SERVICE_LOG, host, port);
+        RResult result = restTemplate.getForObject(restUrl, RResult.class, param);
+        return result;
+    }
+
+    public RResult taskInfo(String host, Integer port, String taskId) {
+        Map<String, Object> param = Maps.newHashMap();
+        param.put("taskId", taskId);
+        String restUrl = String.format(AGENT_TASK_INFO, host, port);
+        RResult result = restTemplate.getForObject(restUrl, RResult.class, param);
+        return result;
+    }
+
+    public RResult taskLog(String host, Integer port, String taskId) {
+        Map<String, Object> param = Maps.newHashMap();
+        param.put("taskId", taskId);
+        String restUrl = String.format(AGENT_TASK_LOG, host, port);
+        RResult result = restTemplate.getForObject(restUrl, RResult.class, param);
+        return result;
+    }
+
+    public Properties roleConfig(String host, Integer port, String serviceRole) {
+        String restUrl = String.format(SERVICE_CONFIG, host, port);
+        Map<String, Object> param = Maps.newHashMap();
+        param.put("serviceRole", serviceRole);
+        RResult result = restTemplate.getForObject(restUrl, RResult.class, param);
+        Properties roleConf = new Properties();
+        if (result != null && result.isSuccess()) {
+            roleConf = JSON.parseObject(JSON.toJSONString(result.getData()), Properties.class);
+        }
+        return roleConf;
+    }
+
+    public HardwareInfo hardwareInfo(String host, Integer port) {
+        String restUrl = String.format(HARDWARE_INFO, host, port);
+        RResult result = restTemplate.getForObject(restUrl, RResult.class);
+        HardwareInfo hardware = null;
+        if (result != null && result.isSuccess()) {
+            hardware = JSON.parseObject(JSON.toJSONString(result.getData()), HardwareInfo.class);
+        }
+        return hardware;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentTaskStatusRunner.java b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentTaskStatusRunner.java
new file mode 100644
index 0000000..2c970f9
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/agent/AgentTaskStatusRunner.java
@@ -0,0 +1,68 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.agent;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.stack.dao.ProcessInstanceRepository;
+import org.apache.doris.stack.entity.ProcessInstanceEntity;
+import org.apache.doris.stack.service.ProcessTask;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * agent task status check
+ **/
+@Component
+@Slf4j
+public class AgentTaskStatusRunner implements ApplicationRunner {
+
+    private static final long REFRESH_TIME = 10 * 1000L;
+    private static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+
+    @Autowired
+    private ProcessTask processTask;
+
+    @Autowired
+    private ProcessInstanceRepository processInstanceRepository;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        this.scheduler.scheduleWithFixedDelay(() -> {
+            try {
+                refreshTaskStatus();
+            } catch (Exception ex) {
+                log.error("refresh agent task fail:", ex);
+                ex.printStackTrace();
+            }
+        }, REFRESH_TIME, REFRESH_TIME, TimeUnit.MILLISECONDS);
+    }
+
+    private void refreshTaskStatus() {
+        List<ProcessInstanceEntity> processEntities = processInstanceRepository.queryProcessList();
+        for (ProcessInstanceEntity process : processEntities) {
+            processTask.refreshAgentTaskStatus(process.getId());
+        }
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/bean/SpringApplicationContext.java b/manager/dm-server/src/main/java/org/apache/doris/stack/bean/SpringApplicationContext.java
new file mode 100644
index 0000000..bbc7716
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/bean/SpringApplicationContext.java
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.bean;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SpringApplicationContext implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    public static <T> T getBean(Class<T> requiredType) {
+        return applicationContext.getBean(requiredType);
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringApplicationContext.applicationContext = applicationContext;
+    }
+
+    /**
+     * Close this application context, destroying all beans in its bean factory.
+     */
+    public void close() {
+        ((AbstractApplicationContext) applicationContext).close();
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/component/AgentComponent.java b/manager/dm-server/src/main/java/org/apache/doris/stack/component/AgentComponent.java
new file mode 100644
index 0000000..fdb313d
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/component/AgentComponent.java
@@ -0,0 +1,87 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.component;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.doris.stack.constants.AgentStatus;
+import org.apache.doris.stack.dao.AgentRepository;
+import org.apache.doris.stack.entity.AgentEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+
+@Component
+@Slf4j
+public class AgentComponent {
+
+    @Autowired
+    private AgentRepository agentRepository;
+
+    public List<AgentEntity> queryAgentNodes(List<String> hosts) {
+        if (hosts == null || hosts.isEmpty()) {
+            return agentRepository.findAll();
+        }
+        return agentRepository.queryAgentNodes(hosts);
+    }
+
+    public List<AgentEntity> queryAgentNodes(int clusterId) {
+        return agentRepository.queryAgentNodesByClusterId(clusterId);
+    }
+
+    public AgentEntity agentInfo(String host) {
+        List<AgentEntity> agentEntities = agentRepository.agentInfo(host);
+        if (agentEntities != null && !agentEntities.isEmpty()) {
+            return agentEntities.get(0);
+        } else {
+            return null;
+        }
+    }
+
+    public boolean refreshAgentStatus(String host, Integer port) {
+        AgentEntity agentInfo = agentInfo(host);
+        if (agentInfo == null) {
+            return false;
+        }
+        agentInfo.setStatus(AgentStatus.RUNNING);
+        agentInfo.setLastReportedTime(new Date());
+        agentRepository.save(agentInfo);
+        return true;
+    }
+
+    public AgentEntity saveAgent(AgentEntity agent) {
+        if (agent.getId() == 0 && StringUtils.isNotBlank(agent.getHost())) {
+            //When retry installing the agent, overwrite the previously installed
+            AgentEntity agentEntity = agentInfo(agent.getHost());
+            if (agentEntity != null) {
+                agent.setId(agentEntity.getId());
+            }
+        }
+        return agentRepository.save(agent);
+    }
+
+    public void removeAgent(String agentHost) {
+        AgentEntity agentEntity = agentInfo(agentHost);
+        if (agentEntity != null) {
+            agentRepository.deleteById(agentEntity.getId());
+        }
+    }
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/component/AgentRoleComponent.java b/manager/dm-server/src/main/java/org/apache/doris/stack/component/AgentRoleComponent.java
new file mode 100644
index 0000000..c0fe5c9
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/component/AgentRoleComponent.java
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.component;
+
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.doris.stack.dao.AgentRoleRepository;
+import org.apache.doris.stack.entity.AgentRoleEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@Slf4j
+public class AgentRoleComponent {
+
+    @Autowired
+    private AgentRoleRepository agentRoleRepository;
+
+    public List<AgentRoleEntity> queryAllAgentRoles() {
+        return agentRoleRepository.findAll();
+    }
+
+    public List<AgentRoleEntity> queryAgentRoles(int clusterId) {
+        return agentRoleRepository.queryAgentRoles(clusterId);
+    }
+
+    public List<AgentRoleEntity> queryAgentByRole(String role, int clusterId) {
+        if (StringUtils.isBlank(role)) {
+            return agentRoleRepository.queryAgentRoles(clusterId);
+        }
+        return agentRoleRepository.queryAgentByRole(role, clusterId);
+    }
+
+    public List<AgentRoleEntity> queryAgentByHost(String host) {
+        if (StringUtils.isBlank(host)) {
+            return Lists.newArrayList();
+        }
+        return agentRoleRepository.queryAgentByHost(host);
+    }
+
+    public AgentRoleEntity queryByHostRole(String host, String role) {
+        return agentRoleRepository.queryByHostRole(host, role);
+    }
+
+    public AgentRoleEntity saveAgentRole(AgentRoleEntity agentRoleEntity) {
+        return agentRoleRepository.save(agentRoleEntity);
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/component/ProcessInstanceComponent.java b/manager/dm-server/src/main/java/org/apache/doris/stack/component/ProcessInstanceComponent.java
new file mode 100644
index 0000000..291a4d6
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/component/ProcessInstanceComponent.java
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.component;
+
+import com.google.common.base.Preconditions;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.stack.constants.Flag;
+import org.apache.doris.stack.constants.ProcessTypeEnum;
+import org.apache.doris.stack.dao.ProcessInstanceRepository;
+import org.apache.doris.stack.entity.ProcessInstanceEntity;
+import org.apache.doris.stack.exceptions.ServerException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.Optional;
+
+@Component
+@Slf4j
+public class ProcessInstanceComponent {
+
+    @Autowired
+    private ProcessInstanceRepository processInstanceRepository;
+
+    /**
+     * save process and return id
+     */
+    public int saveProcess(ProcessInstanceEntity processInstance) {
+        checkHasUnfinishProcess(processInstance.getUserId(), processInstance.getId());
+        return processInstanceRepository.save(processInstance).getId();
+    }
+
+    /**
+     * check process is finished
+     */
+    public void checkProcessFinish(int processId) {
+        Optional<ProcessInstanceEntity> optional = processInstanceRepository.findById(processId);
+        Preconditions.checkArgument(optional.isPresent(), "install process is not exist");
+        ProcessInstanceEntity processEntity = optional.get();
+        if (Flag.YES.equals(processEntity.getFinish())) {
+            throw new ServerException("install process " + processId + " is already finish");
+        }
+    }
+
+    public void checkHasUnfinishProcess(int userId, int processId) {
+        //query whether there is a process currently being installed
+        ProcessInstanceEntity processEntity = processInstanceRepository.queryProcessByuserId(userId);
+        if (processEntity != null && processEntity.getId() != processId) {
+            throw new ServerException("You already have an installation in the current environment!");
+        }
+    }
+
+    public ProcessInstanceEntity refreshProcess(int processId, ProcessTypeEnum processType) {
+        ProcessInstanceEntity processInstance = queryProcessById(processId);
+        Preconditions.checkArgument(processInstance != null, "install process is not exist");
+        processInstance.setProcessType(processType);
+        return processInstanceRepository.save(processInstance);
+    }
+
+    public ProcessInstanceEntity queryProcessByuserId(int userId) {
+        return processInstanceRepository.queryProcessByuserId(userId);
+    }
+
+    /**
+     * query process by id
+     */
+    public ProcessInstanceEntity queryProcessById(int processId) {
+        Optional<ProcessInstanceEntity> optional = processInstanceRepository.findById(processId);
+        if (optional.isPresent()) {
+            return optional.get();
+        }
+        return null;
+    }
+
+    /**
+     * finish process
+     */
+    public void finishProcess(ProcessInstanceEntity processInstance) {
+        processInstance.setFinish(Flag.YES);
+        processInstance.setUpdateTime(new Date());
+        processInstanceRepository.save(processInstance);
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/component/TaskInstanceComponent.java b/manager/dm-server/src/main/java/org/apache/doris/stack/component/TaskInstanceComponent.java
new file mode 100644
index 0000000..d976613
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/component/TaskInstanceComponent.java
@@ -0,0 +1,167 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.component;
+
+import com.alibaba.fastjson.JSON;
+import com.google.common.collect.Lists;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.doris.manager.common.domain.CommandResult;
+import org.apache.doris.manager.common.domain.RResult;
+import org.apache.doris.manager.common.domain.TaskResult;
+import org.apache.doris.stack.constants.ExecutionStatus;
+import org.apache.doris.stack.constants.Flag;
+import org.apache.doris.stack.constants.ProcessTypeEnum;
+import org.apache.doris.stack.constants.TaskTypeEnum;
+import org.apache.doris.stack.dao.TaskInstanceRepository;
+import org.apache.doris.stack.entity.TaskInstanceEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+@Component
+@Slf4j
+public class TaskInstanceComponent {
+
+    @Autowired
+    private TaskInstanceRepository taskInstanceRepository;
+
+    /**
+     * The same host, the same tasktype, can only have one in a install process
+     */
+    public boolean checkTaskRunning(int processId, String host, ProcessTypeEnum processType, TaskTypeEnum taskType) {
+        TaskInstanceEntity taskEntity = taskInstanceRepository.queryTask(processId, host, processType, taskType);
+        if (taskEntity == null) {
+            return false;
+        } else if (taskEntity.getStatus().typeIsRunning()) {
+            log.warn("task {} already running in host {}", taskType.name(), host);
+            return true;
+        } else {
+            taskInstanceRepository.deleteById(taskEntity.getId());
+            return false;
+        }
+    }
+
+    /**
+     * If the same task is already running on the host, skip it
+     */
+    public TaskInstanceEntity saveTask(int processId, String host, ProcessTypeEnum processType, TaskTypeEnum taskType, ExecutionStatus status) {
+        if (!checkTaskRunning(processId, host, processType, taskType)) {
+            return taskInstanceRepository.save(new TaskInstanceEntity(processId, host, processType, taskType, status));
+        } else {
+            log.warn("task {} is already running on the host {}", taskType, host);
+            return null;
+        }
+    }
+
+    public TaskInstanceEntity saveTask(TaskInstanceEntity task) {
+        return saveTask(task.getProcessId(), task.getHost(), task.getProcessType(), task.getTaskType(), task.getStatus());
+    }
+
+    /**
+     * refresh task status
+     */
+    public TaskInstanceEntity refreshTask(TaskInstanceEntity taskInstance, RResult result) {
+        if (result == null || result.getData() == null) {
+            taskInstance.setStatus(ExecutionStatus.FAILURE);
+        } else {
+            CommandResult commandResult = JSON.parseObject(JSON.toJSONString(result.getData()), CommandResult.class);
+            if (commandResult == null) {
+                taskInstance.setStatus(ExecutionStatus.FAILURE);
+            } else {
+                TaskResult taskResult = commandResult.getTaskResult();
+                if (taskResult == null) {
+                    taskInstance.setStatus(ExecutionStatus.FAILURE);
+                } else {
+                    taskInstance.setExecutorId(taskResult.getTaskId());
+                    if (taskResult.getTaskState().typeIsRunning()) {
+                        taskInstance.setStatus(ExecutionStatus.RUNNING);
+                    } else if (taskResult.getRetCode() != null && taskResult.getRetCode() == 0) {
+                        taskInstance.setStatus(ExecutionStatus.SUCCESS);
+                        taskInstance.setFinish(Flag.YES);
+                        taskInstance.setEndTime(new Date());
+                    } else {
+                        taskInstance.setStatus(ExecutionStatus.FAILURE);
+                        taskInstance.setEndTime(new Date());
+                    }
+                }
+            }
+        }
+        return taskInstanceRepository.save(taskInstance);
+    }
+
+    /**
+     * Check whether the task is successful
+     */
+    public boolean checkTaskSuccess(int processId, ProcessTypeEnum processType) {
+        List<TaskInstanceEntity> taskInstanceEntities = taskInstanceRepository.queryTasksByProcessStep(processId, processType);
+        if (ObjectUtils.isEmpty(taskInstanceEntities)) {
+            log.error("parent step {} has no task", processType.name());
+            return false;
+        }
+        for (TaskInstanceEntity task : taskInstanceEntities) {
+            if (Flag.NO.equals(task.getFinish())) {
+                log.error("task {} is unfinish", task.getTaskType());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * query task by id
+     */
+    public TaskInstanceEntity queryTaskById(int taskId) {
+        Optional<TaskInstanceEntity> optional = taskInstanceRepository.findById(taskId);
+        if (optional.isPresent()) {
+            return optional.get();
+        }
+        return null;
+    }
+
+    /**
+     * query running task
+     */
+    public List<TaskInstanceEntity> queryRunningTasks(int processId, TaskTypeEnum taskType) {
+        List<TaskInstanceEntity> runningTask = Lists.newArrayList();
+        List<TaskInstanceEntity> tasks = taskInstanceRepository.queryTasks(processId, taskType);
+        for (TaskInstanceEntity task : tasks) {
+            if (task.getStatus().typeIsRunning()) {
+                runningTask.add(task);
+            }
+        }
+        return runningTask;
+    }
+
+    /**
+     * query success task
+     */
+    public List<TaskInstanceEntity> querySuccessTasks(int processId, TaskTypeEnum taskType) {
+        List<TaskInstanceEntity> successTask = Lists.newArrayList();
+        List<TaskInstanceEntity> tasks = taskInstanceRepository.queryTasks(processId, taskType);
+        for (TaskInstanceEntity task : tasks) {
+            if (task.getStatus().typeIsSuccess()) {
+                successTask.add(task);
+            }
+        }
+        return successTask;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/config/RestTemplateConfig.java b/manager/dm-server/src/main/java/org/apache/doris/stack/config/RestTemplateConfig.java
new file mode 100644
index 0000000..eebdd21
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/config/RestTemplateConfig.java
@@ -0,0 +1,30 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+    @Bean
+    public RestTemplate restTemplate() {
+        return new RestTemplate();
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/constants/AgentStatus.java b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/AgentStatus.java
new file mode 100644
index 0000000..4c6a354
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/AgentStatus.java
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.constants;
+
+public enum AgentStatus {
+    INIT,
+    REGISTER,
+    RUNNING,
+    STOP;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/constants/CmdTypeEnum.java b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/CmdTypeEnum.java
new file mode 100644
index 0000000..5f61bef
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/CmdTypeEnum.java
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.constants;
+
+public enum CmdTypeEnum {
+    START,
+    STOP;
+
+    public static CmdTypeEnum findByName(String name) {
+        for (CmdTypeEnum type : CmdTypeEnum.values()) {
+            if (type.name().equals(name)) {
+                return type;
+            }
+        }
+        return null;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/constants/Constants.java b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/Constants.java
new file mode 100644
index 0000000..c98ebb9
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/Constants.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.constants;
+
+public class Constants {
+
+    public static final String KEY_DORIS_AGENT_START_SCRIPT = "bin/agent_start.sh";
+    public static final String KEY_FE_QUERY_PORT = "query_port";
+    public static final String KEY_FE_EDIT_LOG_PORT = "edit_log_port";
+    public static final String KEY_BE_HEARTBEAT_PORT = "heartbeat_service_port";
+    public static final String KEY_BROKER_IPC_PORT = "broker_ipc_port";
+
+    public static final String DORIS_DEFAULT_QUERY_USER = "root";
+    public static final String DORIS_DEFAULT_QUERY_PASSWORD = "";
+    public static final Integer DORIS_DEFAULT_FE_QUERY_PORT = 9030;
+    public static final Integer DORIS_DEFAULT_FE_EDIT_LOG_PORT = 9010;
+    public static final Integer DORIS_DEFAULT_BROKER_IPC_PORT = 8000;
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/constants/ExecutionStatus.java b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/ExecutionStatus.java
new file mode 100644
index 0000000..266b2dd
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/ExecutionStatus.java
@@ -0,0 +1,88 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.constants;
+
+/**
+ * running status for workflow and task nodes
+ */
+public enum ExecutionStatus {
+
+    /**
+     * status:
+     * 0 submit success
+     * 1 running
+     * 2 failure
+     * 3 success
+     */
+    SUBMITTED(0, "submit success"),
+    RUNNING(1, "running"),
+    FAILURE(2, "failure"),
+    SUCCESS(3, "success");
+
+    private final int code;
+    private final String desc;
+
+    ExecutionStatus(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    /**
+     * status is success
+     *
+     * @return status
+     */
+    public boolean typeIsSuccess() {
+        return this == SUCCESS;
+    }
+
+    /**
+     * status is failure
+     *
+     * @return status
+     */
+    public boolean typeIsFailure() {
+        return this == FAILURE;
+    }
+
+    /**
+     * status is finished
+     *
+     * @return status
+     */
+    public boolean typeIsFinished() {
+        return typeIsSuccess() || typeIsFailure();
+    }
+
+    /**
+     * status is running
+     *
+     * @return status
+     */
+    public boolean typeIsRunning() {
+        return this == RUNNING || this == SUBMITTED;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/constants/Flag.java b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/Flag.java
new file mode 100644
index 0000000..36a3581
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/Flag.java
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.constants;
+
+public enum Flag {
+    /**
+     * 0 no
+     * 1 yes
+     */
+    NO(0, "no"),
+    YES(1, "yes");
+
+    private final int code;
+    private final String desc;
+
+    Flag(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    /**
+     * is yes
+     *
+     * @return status
+     */
+    public boolean typeIsYes() {
+        return this == YES;
+    }
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/constants/ProcessTypeEnum.java b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/ProcessTypeEnum.java
new file mode 100644
index 0000000..d53cfba
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/ProcessTypeEnum.java
@@ -0,0 +1,76 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.constants;
+
+/**
+ * process step type
+ **/
+public enum ProcessTypeEnum {
+    INSTALL_AGENT(0, "install agent"),
+    INSTALL_SERVICE(1, "install service"),
+    DEPLOY_CONFIG(2, "deploy config"),
+    START_SERVICE(3, "start service");
+
+    private int code;
+    private String desc;
+
+    ProcessTypeEnum(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public static ProcessTypeEnum findByName(String name) {
+        for (ProcessTypeEnum type : ProcessTypeEnum.values()) {
+            if (type.name().equals(name)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    public static ProcessTypeEnum findByCode(int code) {
+        for (ProcessTypeEnum type : ProcessTypeEnum.values()) {
+            if (type.code == code) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+    public static ProcessTypeEnum findParent(ProcessTypeEnum processType) {
+        if (processType != null) {
+            int parentCode = processType.getCode() - 1;
+            return findByCode(parentCode);
+        } else {
+            return processType;
+        }
+    }
+
+    public boolean endProcess() {
+        return this == START_SERVICE;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/constants/TaskTypeEnum.java b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/TaskTypeEnum.java
new file mode 100644
index 0000000..936ae16
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/constants/TaskTypeEnum.java
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.constants;
+
+import org.apache.doris.manager.common.domain.ServiceRole;
+
+/**
+ * task type
+ **/
+public enum TaskTypeEnum {
+    INSTALL_AGENT("install agent"),
+    INSTALL_FE("install fe"),
+    INSTALL_BE("install be"),
+    DEPLOY_FE_CONFIG("deploy fe config"),
+    DEPLOY_BE_CONFIG("deploy be config"),
+    START_FE("start fe"),
+    START_BE("start be"),
+    STOP_FE("stop fe"),
+    STOP_BE("stop fe"),
+    JOIN_BE("build cluster"),
+    INSTALL_BROKER("install broker"),
+    DEPLOY_BROKER_CONFIG("deploy broker config"),
+    START_BROKER("start broker"),
+    STOP_BROKER("stop broker");
+
+    private String name;
+
+    TaskTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * agent side task
+     */
+    public boolean agentTask() {
+        return this != INSTALL_AGENT && this != JOIN_BE;
+    }
+
+    /**
+     * parse task role: FE BE BROKER
+     */
+    public String parseTaskRole() {
+        if (this == INSTALL_FE
+                || this == DEPLOY_FE_CONFIG
+                || this == START_FE
+                || this == STOP_FE) {
+            return ServiceRole.FE.name();
+        } else if (this == INSTALL_BE
+                || this == DEPLOY_BE_CONFIG
+                || this == START_BE
+                || this == STOP_BE) {
+            return ServiceRole.BE.name();
+        } else if (this == INSTALL_BROKER
+                || this == DEPLOY_BROKER_CONFIG
+                || this == START_BROKER
+                || this == STOP_BROKER) {
+            return ServiceRole.BROKER.name();
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/controller/AgentController.java b/manager/dm-server/src/main/java/org/apache/doris/stack/controller/AgentController.java
new file mode 100644
index 0000000..b296b53
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/controller/AgentController.java
@@ -0,0 +1,133 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.doris.manager.common.domain.AgentRoleRegister;
+import org.apache.doris.manager.common.domain.RResult;
+import org.apache.doris.stack.model.request.BuildClusterReq;
+import org.apache.doris.stack.model.request.DeployConfigReq;
+import org.apache.doris.stack.model.request.DorisExecReq;
+import org.apache.doris.stack.model.request.DorisInstallReq;
+import org.apache.doris.stack.model.request.DorisStartReq;
+import org.apache.doris.stack.service.AgentProcess;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+@Api(tags = "Agent API")
+@RestController
+@RequestMapping("/api/agent")
+public class AgentController {
+
+    @Autowired
+    private AgentProcess agentProcess;
+
+    /**
+     * install doris service
+     */
+    @ApiOperation(value = "install doris service")
+    @RequestMapping(value = "/installService", method = RequestMethod.POST)
+    public RResult installService(HttpServletRequest request, HttpServletResponse response,
+                                  @RequestBody DorisInstallReq installReq) throws Exception {
+        agentProcess.installService(request, response, installReq);
+        return RResult.success();
+    }
+
+    /**
+     * deploy config
+     */
+    @ApiOperation(value = "deploy doris config")
+    @RequestMapping(value = "/deployConfig", method = RequestMethod.POST)
+    public RResult deployConfig(HttpServletRequest request, HttpServletResponse response,
+                                @RequestBody DeployConfigReq deployConfigReq) throws Exception {
+        agentProcess.deployConfig(request, response, deployConfigReq);
+        return RResult.success();
+    }
+
+    /**
+     * Start the service when installing the cluster
+     */
+    @ApiOperation(value = "Start the service when installing the cluster")
+    @RequestMapping(value = "/startService", method = RequestMethod.POST)
+    public RResult startService(HttpServletRequest request, HttpServletResponse response,
+                                @RequestBody DorisStartReq dorisStart) throws Exception {
+        agentProcess.startService(request, response, dorisStart);
+        return RResult.success();
+    }
+
+    /**
+     * build cluster add backend,add fe,add broker
+     */
+    @ApiOperation(value = "build cluster")
+    @RequestMapping(value = "/buildCluster", method = RequestMethod.POST)
+    public RResult buildCluster(HttpServletRequest request, HttpServletResponse response,
+                          @RequestBody BuildClusterReq buildClusterReq) throws Exception {
+        agentProcess.buildCluster(request, response, buildClusterReq);
+        return RResult.success();
+    }
+
+    /**
+     * register role service (be/fe/broker)
+     */
+    @ApiOperation(value = "register role service (be/fe/broker)")
+    @RequestMapping(value = "/register", method = RequestMethod.POST)
+    public RResult register(@RequestBody AgentRoleRegister agentReg) {
+        boolean register = agentProcess.register(agentReg);
+        return RResult.success(register);
+    }
+
+    /**
+     * execute command: START/STOP
+     */
+    @ApiOperation(value = "execute command:START/STOP")
+    @RequestMapping(value = "/execute", method = RequestMethod.POST)
+    public RResult execute(@RequestBody DorisExecReq dorisExec) {
+        List<Integer> taskIds = agentProcess.execute(dorisExec);
+        return RResult.success(taskIds);
+    }
+
+    /**
+     * query log
+     * type:fe.log/fe.out/be.log/be.out
+     */
+    @ApiOperation(value = "query service log,type:fe.log|fe.out|be.log|be.out")
+    @RequestMapping(value = "/log", method = RequestMethod.GET)
+    public RResult log(@RequestParam String host, @RequestParam String type) {
+        return RResult.success(agentProcess.log(host, type));
+    }
+
+    /**
+     * query hardware info
+     */
+    @ApiOperation(value = "query hardware info")
+    @RequestMapping(value = "/hardware/{clusterId}", method = RequestMethod.GET)
+    public RResult hardwareInfo(@PathVariable int clusterId) {
+        return RResult.success(agentProcess.hardwareInfo(clusterId));
+    }
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/controller/ProcessTaskController.java b/manager/dm-server/src/main/java/org/apache/doris/stack/controller/ProcessTaskController.java
new file mode 100644
index 0000000..2ded928
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/controller/ProcessTaskController.java
@@ -0,0 +1,146 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.doris.manager.common.domain.RResult;
+import org.apache.doris.stack.entity.TaskInstanceEntity;
+import org.apache.doris.stack.model.response.CurrentProcessResp;
+import org.apache.doris.stack.model.response.TaskInstanceResp;
+import org.apache.doris.stack.service.ProcessTask;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * process task controller
+ **/
+@Api(tags = "Process Task API")
+@RestController
+@RequestMapping("/api/process")
+public class ProcessTaskController {
+
+    @Autowired
+    private ProcessTask processTask;
+
+    /**
+     * query user current installation progress
+     */
+    @ApiOperation(value = "query user current installation process")
+    @RequestMapping(value = "/currentProcess", method = RequestMethod.GET)
+    public RResult currentProcess(HttpServletRequest request, HttpServletResponse response) throws Exception {
+        CurrentProcessResp process = processTask.currentProcess(request, response);
+        return RResult.success(process);
+    }
+
+    /**
+     * Installation progress of the current process
+     */
+    @ApiOperation(value = "query user history installation progress")
+    @RequestMapping(value = "/{processId}/progress", method = RequestMethod.GET)
+    public RResult processProgress(HttpServletRequest request, HttpServletResponse response,
+                                   @PathVariable(value = "processId") int processId) {
+        List<TaskInstanceEntity> tasks = processTask.processProgress(request, response, processId);
+        return RResult.success(tasks);
+    }
+
+    /**
+     * Query the installation status of tasks in the current installation process
+     */
+    @ApiOperation(value = "Query the installation status of tasks in the current installation process")
+    @RequestMapping(value = "/{processId}/currentTasks", method = RequestMethod.GET)
+    public RResult taskProgress(HttpServletRequest request, HttpServletResponse response,
+                                @PathVariable(value = "processId") int processId) {
+        List<TaskInstanceResp> tasks = processTask.taskProgress(request, response, processId);
+        return RResult.success(tasks);
+    }
+
+    /**
+     * After the installation is complete, call the interface
+     */
+    @ApiOperation(value = "After the installation is complete, call the interface")
+    @RequestMapping(value = "/installComplete/{processId}", method = RequestMethod.POST)
+    public RResult installComplete(HttpServletRequest request, HttpServletResponse response,
+                                   @PathVariable(value = "processId") int processId) throws Exception {
+        processTask.installComplete(request, response, processId);
+        return RResult.success();
+    }
+
+    /**
+     * cancel process
+     */
+    @ApiOperation(value = "cancel process")
+    @RequestMapping(value = "/cancel/{processId}", method = RequestMethod.POST)
+    public RResult cancelProcess(HttpServletRequest request, HttpServletResponse response,
+                                 @PathVariable(value = "processId") int processId) throws Exception {
+        processTask.cancelProcess(request, response, processId);
+        return RResult.success();
+    }
+
+    /**
+     * Skip task when task fails
+     */
+    @ApiOperation(value = "Skip task when task fails")
+    @RequestMapping(value = "/task/skip/{taskId}", method = RequestMethod.POST)
+    public RResult skipTask(@PathVariable(value = "taskId") int taskId) {
+        processTask.skipTask(taskId);
+        return RResult.success();
+    }
+
+    /**
+     * retry task when task fails
+     */
+    @ApiOperation(value = "retry task when task fails")
+    @RequestMapping(value = "/task/retry/{taskId}", method = RequestMethod.POST)
+    public RResult retryTask(@PathVariable(value = "taskId") int taskId) {
+        processTask.retryTask(taskId);
+        return RResult.success();
+    }
+
+    /**
+     * request task info
+     */
+    @RequestMapping(value = "/task/info/{taskId}", method = RequestMethod.GET)
+    public RResult taskInfo(@PathVariable int taskId) {
+        return RResult.success(processTask.taskInfo(taskId));
+    }
+
+    /**
+     * request task stdout log
+     */
+    @RequestMapping(value = "/task/log/{taskId}", method = RequestMethod.GET)
+    public RResult taskLog(@PathVariable int taskId) {
+        return RResult.success(processTask.taskLog(taskId));
+    }
+
+    /**
+     * Go back to the previous step
+     */
+    @RequestMapping(value = "/back/{processId}", method = RequestMethod.POST)
+    public RResult backPrevious(@PathVariable int processId) {
+        processTask.backPrevious(processId);
+        return RResult.success();
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/controller/ServerController.java b/manager/dm-server/src/main/java/org/apache/doris/stack/controller/ServerController.java
new file mode 100644
index 0000000..de05db7
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/controller/ServerController.java
@@ -0,0 +1,106 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.manager.common.domain.RResult;
+import org.apache.doris.stack.model.request.AgentCommon;
+import org.apache.doris.stack.model.request.AgentInstallReq;
+import org.apache.doris.stack.model.request.AgentRegister;
+import org.apache.doris.stack.service.ServerProcess;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Api(tags = "Server API")
+@RestController
+@RequestMapping("/api/server")
+@Slf4j
+public class ServerController {
+
+    @Autowired
+    private ServerProcess serverProcess;
+
+    /**
+     * install and start agent and return processId
+     */
+    @ApiOperation(value = "install agent and return processId")
+    @RequestMapping(value = "/installAgent", method = RequestMethod.POST)
+    public RResult installAgents(HttpServletRequest request, HttpServletResponse response,
+                                 @RequestBody AgentInstallReq agentInstallReq) throws Exception {
+        int processId = serverProcess.installAgent(request, response, agentInstallReq);
+        return RResult.success(processId);
+    }
+
+    /**
+     * agent info list
+     */
+    @ApiOperation(value = "agent info list")
+    @RequestMapping(value = "/agentList", method = RequestMethod.GET)
+    public RResult agentList(@RequestParam int clusterId) {
+        return RResult.success(serverProcess.agentList(clusterId));
+    }
+
+    /**
+     * role info list
+     */
+    @ApiOperation(value = "agent role info list")
+    @RequestMapping(value = "/roleList", method = RequestMethod.GET)
+    public RResult roleList(@RequestParam int clusterId) {
+        return RResult.success(serverProcess.roleList(clusterId));
+    }
+
+    /**
+     * agent role info
+     */
+    @ApiOperation(value = "agent role info")
+    @RequestMapping(value = "/agentRole", method = RequestMethod.GET)
+    public RResult agentRole(@RequestParam String host) {
+        return RResult.success(serverProcess.agentRole(host));
+    }
+
+    /**
+     * heatbeat report api
+     */
+    @ApiOperation(value = "agent heartbeat report")
+    @RequestMapping(value = "/heartbeat", method = RequestMethod.POST)
+    public RResult heartbeat(@RequestBody AgentCommon agent) {
+        log.info("{} heartbeat.", agent.getHost());
+        serverProcess.heartbeat(agent.getHost(), agent.getPort());
+        return RResult.success();
+    }
+
+    /**
+     * register agent
+     */
+    @ApiOperation(value = "agent register")
+    @RequestMapping(value = "/register", method = RequestMethod.POST)
+    public RResult register(@RequestBody AgentRegister agent) {
+        log.info("{} register.", agent.getHost());
+        boolean register = serverProcess.register(agent);
+        return RResult.success(register);
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/dao/AgentRepository.java b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/AgentRepository.java
new file mode 100644
index 0000000..f080dd6
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/AgentRepository.java
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.dao;
+
+import org.apache.doris.stack.entity.AgentEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface AgentRepository extends JpaRepository<AgentEntity, Integer> {
+
+    @Query("select f from AgentEntity f where f.host in (:hosts)")
+    List<AgentEntity> queryAgentNodes(@Param("hosts") List<String> hosts);
+
+    @Query("select f from AgentEntity f where f.host = :host ")
+    List<AgentEntity> agentInfo(@Param("host") String host);
+
+    @Query("select f from AgentEntity f where f.clusterId = :clusterId")
+    List<AgentEntity> queryAgentNodesByClusterId(@Param("clusterId") int clusterId);
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/dao/AgentRoleRepository.java b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/AgentRoleRepository.java
new file mode 100644
index 0000000..c36dc86
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/AgentRoleRepository.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.dao;
+
+import org.apache.doris.stack.entity.AgentRoleEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface AgentRoleRepository extends JpaRepository<AgentRoleEntity, Integer> {
+
+    @Query("select f from AgentRoleEntity f where f.role = :role and f.clusterId = :clusterId")
+    List<AgentRoleEntity> queryAgentByRole(@Param("role") String role, @Param("clusterId") int clusterId);
+
+    @Query("select f from AgentRoleEntity f where f.host = :host")
+    List<AgentRoleEntity> queryAgentByHost(@Param("host") String host);
+
+    @Query("select f from AgentRoleEntity f where f.host = :host and f.role = :role")
+    AgentRoleEntity queryByHostRole(@Param("host") String host, @Param("role") String role);
+
+    @Query("select f from AgentRoleEntity f where f.clusterId = :clusterId")
+    List<AgentRoleEntity> queryAgentRoles(@Param("clusterId") int clusterId);
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/dao/ProcessInstanceRepository.java b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/ProcessInstanceRepository.java
new file mode 100644
index 0000000..3c8b35c
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/ProcessInstanceRepository.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.dao;
+
+import org.apache.doris.stack.entity.ProcessInstanceEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface ProcessInstanceRepository extends JpaRepository<ProcessInstanceEntity, Integer> {
+
+    @Query("select f from ProcessInstanceEntity f where f.userId = :userId and finish = 0")
+    ProcessInstanceEntity queryProcessByuserId(@Param("userId") int userId);
+
+    @Query("select f from ProcessInstanceEntity f where  finish = 0")
+    List<ProcessInstanceEntity> queryProcessList();
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/dao/TaskInstanceRepository.java b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/TaskInstanceRepository.java
new file mode 100644
index 0000000..63b4697
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/dao/TaskInstanceRepository.java
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.dao;
+
+import org.apache.doris.stack.constants.ProcessTypeEnum;
+import org.apache.doris.stack.constants.TaskTypeEnum;
+import org.apache.doris.stack.entity.TaskInstanceEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface TaskInstanceRepository extends JpaRepository<TaskInstanceEntity, Integer> {
+
+    @Query("select f from TaskInstanceEntity f where f.processId = :processId")
+    List<TaskInstanceEntity> queryTasksByProcessId(@Param("processId") int processId);
+
+    @Query("select f from TaskInstanceEntity f where f.processId = :processId and f.processType = :processType")
+    List<TaskInstanceEntity> queryTasksByProcessStep(@Param("processId") int processId, @Param("processType") ProcessTypeEnum processType);
+
+    @Query("select f from TaskInstanceEntity f where f.processId = :processId and host = :host and processType = :processType and taskType = :taskType")
+    TaskInstanceEntity queryTask(@Param("processId") int processId, @Param("host") String host, @Param("processType") ProcessTypeEnum processType, @Param("taskType") TaskTypeEnum taskType);
+
+    @Query("select f from TaskInstanceEntity f where f.processId = :processId and taskType = :taskType order by f.id asc")
+    List<TaskInstanceEntity> queryTasks(@Param("processId") int processId, @Param("taskType") TaskTypeEnum taskType);
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/entity/AgentEntity.java b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/AgentEntity.java
new file mode 100644
index 0000000..15ba450
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/AgentEntity.java
@@ -0,0 +1,84 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.doris.stack.constants.AgentStatus;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Date;
+
+/**
+ * agent entity
+ **/
+@Entity
+@Table(name = "agent")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AgentEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+
+    @Column(name = "host")
+    private String host;
+
+    @Column(name = "port")
+    private int port;
+
+    @Column(name = "cluster_id")
+    private int clusterId;
+
+    @Column(name = "install_dir", length = 1024)
+    private String installDir;
+
+    @Enumerated(EnumType.STRING)
+    private AgentStatus status;
+
+    @Column(name = "register_time")
+    private Date registerTime;
+
+    @Column(name = "last_reported_time")
+    private Date lastReportedTime;
+
+    public AgentEntity(String host, int port, String installDir, AgentStatus status) {
+        this.host = host;
+        this.port = port;
+        this.installDir = installDir;
+        this.status = status;
+        this.registerTime = new Date();
+    }
+
+    public AgentEntity(String host, String installDir, AgentStatus status, int clusterId) {
+        this.host = host;
+        this.installDir = installDir;
+        this.status = status;
+        this.clusterId = clusterId;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/entity/AgentRoleEntity.java b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/AgentRoleEntity.java
new file mode 100644
index 0000000..a4110ae
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/AgentRoleEntity.java
@@ -0,0 +1,69 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.doris.stack.constants.Flag;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "agent_role")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AgentRoleEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+
+    @Column
+    private String host;
+
+    @Column(name = "cluster_id")
+    private int clusterId;
+
+    @Column(name = "role")
+    private String role;
+
+    //FOLLOWER / OBSERVER
+    @Column(name = "fe_node_type")
+    private String feNodeType;
+
+    @Column(name = "install_dir", length = 1024)
+    private String installDir;
+
+    @Column(name = "register")
+    private Flag register;
+
+    public AgentRoleEntity(String host, String role, String feNodeType, String installDir, Flag register) {
+        this.host = host;
+        this.role = role;
+        this.feNodeType = feNodeType;
+        this.installDir = installDir;
+        this.register = register;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/entity/ProcessInstanceEntity.java b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/ProcessInstanceEntity.java
new file mode 100644
index 0000000..ff3b338
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/ProcessInstanceEntity.java
@@ -0,0 +1,105 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.doris.stack.constants.ExecutionStatus;
+import org.apache.doris.stack.constants.Flag;
+import org.apache.doris.stack.constants.ProcessTypeEnum;
+import org.apache.doris.stack.model.response.CurrentProcessResp;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Date;
+
+/**
+ * process instance entity
+ **/
+@Entity
+@Table(name = "process_instance")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProcessInstanceEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+
+    @Column(name = "cluster_id", nullable = false)
+    private int clusterId;
+
+    @Column(name = "user_id", nullable = false)
+    private int userId;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "process_type", nullable = false)
+    private ProcessTypeEnum processType;
+
+    @Column(name = "create_time", nullable = false)
+    private Date createTime;
+
+    @Column(name = "update_time", nullable = false)
+    private Date updateTime;
+
+    @Enumerated(EnumType.ORDINAL)
+    @Column(name = "finish", nullable = false)
+    private Flag finish;
+
+    @Column(name = "package_url", length = 1024)
+    private String packageUrl;
+
+    @Column(name = "install_dir", length = 1024)
+    private String installDir;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "status", nullable = false)
+    private ExecutionStatus status;
+
+    public ProcessInstanceEntity(int clusterId, int userId, ProcessTypeEnum processType, String packageUrl, String installDir) {
+        this.clusterId = clusterId;
+        this.userId = userId;
+        this.processType = processType;
+        this.installDir = installDir;
+        this.packageUrl = packageUrl;
+        this.createTime = new Date();
+        this.updateTime = new Date();
+        this.finish = Flag.NO;
+        this.status = ExecutionStatus.RUNNING;
+    }
+
+    public CurrentProcessResp transToCurrentResp() {
+        CurrentProcessResp processResp = new CurrentProcessResp();
+        processResp.setId(id);
+        processResp.setClusterId(clusterId);
+        processResp.setProcessType(processType);
+        processResp.setProcessStep(processType.getCode());
+        processResp.setCreateTime(createTime);
+        processResp.setUpdateTime(updateTime);
+        processResp.setStatus(status);
+        return processResp;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/entity/TaskInstanceEntity.java b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/TaskInstanceEntity.java
new file mode 100644
index 0000000..5f3fa54
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/entity/TaskInstanceEntity.java
@@ -0,0 +1,136 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.doris.stack.constants.ExecutionStatus;
+import org.apache.doris.stack.constants.Flag;
+import org.apache.doris.stack.constants.ProcessTypeEnum;
+import org.apache.doris.stack.constants.TaskTypeEnum;
+import org.apache.doris.stack.model.response.TaskInstanceResp;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.util.Date;
+
+/**
+ * task instance entity
+ **/
+@Entity
+@Table(name = "task_instance")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TaskInstanceEntity {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+
+    @Column(name = "process_id")
+    private int processId;
+
+    @Column(name = "task_json", columnDefinition = "LONGTEXT")
+    private String taskJson;
+
+    @Column(name = "host", nullable = false)
+    private String host;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "process_type")
+    private ProcessTypeEnum processType;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "task_type", nullable = false)
+    private TaskTypeEnum taskType;
+
+    @Enumerated(EnumType.STRING)
+    @Column(name = "status", nullable = false)
+    private ExecutionStatus status;
+
+    @Column(name = "start_time", nullable = false)
+    private Date startTime;
+
+    @Column(name = "end_time")
+    private Date endTime;
+
+    @Column(name = "executor_id")
+    private String executorId;
+
+    @Column(name = "result", columnDefinition = "LONGTEXT")
+    private String result;
+
+    @Enumerated(EnumType.ORDINAL)
+    @Column(name = "finish", nullable = false)
+    private Flag finish;
+
+    @Enumerated(EnumType.ORDINAL)
+    @Column(name = "skip", nullable = false)
+    private Flag skip;
+
+    public TaskInstanceEntity(int processId, String host, ProcessTypeEnum processType, TaskTypeEnum taskType, ExecutionStatus status) {
+        this.processId = processId;
+        this.host = host;
+        this.processType = processType;
+        this.taskType = taskType;
+        this.status = status;
+        this.startTime = new Date();
+        this.finish = Flag.NO;
+        this.skip = Flag.NO;
+    }
+
+    public TaskInstanceEntity(int processId, String host, ProcessTypeEnum processType, ExecutionStatus status) {
+        this.processId = processId;
+        this.host = host;
+        this.processType = processType;
+        this.startTime = new Date();
+        this.finish = Flag.NO;
+        this.skip = Flag.NO;
+        this.status = status;
+    }
+
+    public TaskInstanceEntity(String host) {
+        this.host = host;
+        this.startTime = new Date();
+        this.finish = Flag.NO;
+        this.skip = Flag.NO;
+    }
+
+    public TaskInstanceResp transToModel() {
+        TaskInstanceResp taskResp = new TaskInstanceResp();
+        taskResp.setId(id);
+        taskResp.setProcessId(processId);
+        taskResp.setHost(host);
+        taskResp.setProcessType(processType);
+        taskResp.setTaskType(taskType);
+        taskResp.setStatus(status);
+        taskResp.setStartTime(startTime);
+        taskResp.setEndTime(endTime);
+        taskResp.setFinish(finish);
+        taskResp.setSkip(skip);
+        return taskResp;
+    }
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/GlobalExceptionHandler.java b/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/GlobalExceptionHandler.java
new file mode 100644
index 0000000..8cd402c
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/GlobalExceptionHandler.java
@@ -0,0 +1,41 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.exceptions;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.doris.manager.common.domain.RResult;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+@Slf4j
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler(ServerException.class)
+    public RResult handleException(ServerException exception) {
+        log.error(exception.getMessage(), exception);
+        return RResult.error(exception.getStatus(), exception.getMessage());
+    }
+
+    @ExceptionHandler(Throwable.class)
+    public RResult javaExceptionHandler(Exception ex) {
+        log.error("server error ", ex);
+        return RResult.error(5000, "server error");
+    }
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/JdbcException.java b/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/JdbcException.java
new file mode 100644
index 0000000..acaf4cb
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/JdbcException.java
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.exceptions;
+
+public class JdbcException extends ServerException {
+    private static final long SERIAL_VERSION_UID = -1L;
+
+    private static final Integer DEAFULT_EXCEPTION_STATUS = 500;
+
+    private int status;
+
+    public JdbcException(String message) {
+        this(message, DEAFULT_EXCEPTION_STATUS);
+    }
+
+    public JdbcException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public JdbcException(String message, int status) {
+        super(message);
+        this.status = status;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/ServerException.java b/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/ServerException.java
new file mode 100644
index 0000000..6042ca5
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/exceptions/ServerException.java
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.exceptions;
+
+public class ServerException extends RuntimeException {
+    private static final long SERIAL_VERSION_UID = -1L;
+
+    private static final Integer DEAFULT_EXCEPTION_STATUS = 500;
+
+    private int status;
+
+    public ServerException(String message) {
+        this(message, DEAFULT_EXCEPTION_STATUS);
+    }
+
+    public ServerException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ServerException(String message, int status) {
+        super(message);
+        this.status = status;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentCommon.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentCommon.java
new file mode 100644
index 0000000..a454590
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentCommon.java
@@ -0,0 +1,32 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AgentCommon {
+
+    private String host;
+
+    private Integer port;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentInstallReq.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentInstallReq.java
new file mode 100644
index 0000000..5f7c4ad
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentInstallReq.java
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AgentInstallReq {
+
+    private int processId;
+
+    private int clusterId;
+
+    private List<String> hosts;
+
+    private String user;
+
+    private int sshPort;
+
+    private String sshKey;
+
+    private String installDir;
+
+    private String packageUrl;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentRegister.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentRegister.java
new file mode 100644
index 0000000..0b533b5
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/AgentRegister.java
@@ -0,0 +1,34 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AgentRegister {
+
+    private String host;
+
+    private int port;
+
+    private String installDir;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/BuildClusterReq.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/BuildClusterReq.java
new file mode 100644
index 0000000..8de0939
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/BuildClusterReq.java
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * be join cluster req
+ **/
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BuildClusterReq {
+
+    private int processId;
+
+    private List<String> feHosts;
+
+    private List<String> beHosts;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DeployConfigReq.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DeployConfigReq.java
new file mode 100644
index 0000000..fb39fab
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DeployConfigReq.java
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.doris.stack.model.task.DeployConfig;
+
+import java.util.List;
+
+/**
+ * deploy config req
+ **/
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DeployConfigReq {
+
+    List<DeployConfig> deployConfigs;
+    private int processId;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisExecReq.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisExecReq.java
new file mode 100644
index 0000000..f3b36c3
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisExecReq.java
@@ -0,0 +1,38 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * doris exec command req
+ **/
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class DorisExecReq {
+
+    private String command;
+
+    //agent role ids
+    private List<Integer> roles;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisInstallReq.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisInstallReq.java
new file mode 100644
index 0000000..ddb74d8
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisInstallReq.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.doris.stack.model.task.DorisInstall;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DorisInstallReq {
+
+    private int processId;
+
+    private List<DorisInstall> installInfos;
+}
diff --git a/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisStartReq.java b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisStartReq.java
new file mode 100644
index 0000000..699ae14
--- /dev/null
+++ b/manager/dm-server/src/main/java/org/apache/doris/stack/model/request/DorisStartReq.java
@@ -0,0 +1,35 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.stack.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.doris.stack.model.task.DorisStart;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DorisStartReq {
+
+    private int processId;
... 45027 lines suppressed ...

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org